Mybatis多表关联查询的实现(DEMO)
1. 前言
在现实开发中,通常需要查询两个或更多个表的联合结果。这可以通过SQL join
操作实现。Mybatis
框架也提供了多表关联查询的实现,本文将以实例为根据,详细讲解Mybatis
多表关联查询的实现过程。
2. 环境准备
为了实现多表查询,需要先建好需要查询的两个或多个表。此外,还需要安装好Mybatis
框架,以及关联的数据库。
3. 多表查询的实现
3.1 基本SQL语句
多表查询的基本SQL语句如下:
SELECT
table1.column1,
table2.column2,
table2.column3
FROM table1
JOIN table2
ON table1.column4 = table2.column5
WHERE table1.column6 = 'xxx';
其中:
table1
和table2
是需要关联查询的两个表,column1
、column2
、column3
、column4
和column5
是这两个表中的列。table1.column4
和table2.column5
是这两个表中需要进行关联查询的列,JOIN
关键字表示进行join
操作,等于INNER JOIN
。table1.column6
是WHERE
语句中的条件。
3.2 Mapper文件配置
下面以一个实际的示例来演示多表查询的实现,在这个示例中,我们将查询“学生”表和“班级”表,并返回学生姓名、所在班级名称和班级地址。具体操作如下。
- 首先编辑
mapper.xml
文件,创建select
语句。
<select id="getStudents" resultMap="studentMap">
SELECT
stu.student_name,
cls.class_name,
cls.class_address
FROM student stu
JOIN class cls ON stu.class_id = cls.class_id
WHERE stu.student_id = #{id}
</select>
在这个select
语句中,我们使用了JOIN
操作,连接了student
表和class
表。查询学生表中的“学生姓名”,班级表中的“班级名称”和“班级地址”三列。
- 接下来,编辑
resultMap
。
<resultMap id="studentMap" type="Student">
<result property="name" column="student_name"/>
<association property="classInfo" column="class_id" javaType="Class">
<id property="id" column="class_id"/>
<result property="name" column="class_name"/>
<result property="address" column="class_address"/>
</association>
</resultMap>
这里的resultMap
中包含两个result
和一个association
,其中association
表示两个表的关联关系,column
用于指定关联的列,javaType
表示关联的对象类型。在association
中,我们还定义了id
、result
用于映射Class
类的属性。
- 最后,在Java接口中定义方法。
public Student getStudentById(int id);
3.3 示例1
接下来,我们通过一个示例来展示Mybatis
如何执行多表查询。在这个示例中,我们将查询“学生”表中的“学生姓名”、班级表中的“班级名称”和“班级地址”。
- 在
Student
类中定义与数据库中表中列对应的属性。
public class Student {
private int id;
private String name;
private Class classInfo;
// getter/setter
}
在这个Student
类中,我们通过Class
类的属性classInfo
来表示学生所在的班级信息。
- 在
Class
中定义与数据库中表中列对应的属性。
public class Class {
private int id;
private String name;
private String address;
// getter/setter
}
在这个Class
类中,我们定义了ID
、Name
和Address
三个属性,其中的属性与数据库中表中对应的列名一致。
- 然后,在
SqlMapConfig.xml
中配置数据库连接。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis_demo_db"/>
<property name="username" value="mybatis_user"/>
<property name="password" value="mybatis#password"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mapper/StudentMapper.xml"/>
</mappers>
</configuration>
在这个mybatis-config.xml
文件中,我们定义了数据库连接方式,包括连接地址、用户名和密码,然后还指定了包含mapper文件的路径。
- 接下来,在mapper文件中定义实现多表查询的
select
语句。
<select id="getStudentById" resultMap="studentMap">
SELECT
stu.student_id,
stu.student_name,
cls.class_name,
cls.class_address
FROM student stu
JOIN class cls ON stu.class_id = cls.class_id
WHERE stu.student_id = #{id}
</select>
在这个查询语句中,我们查询学生表中的“学生姓名”和关联的班级表中的“班级名称”和“班级地址”。其中,查询语句中使用的JOIN
关键字,表示我们使用的是INNER JOIN
操作。
- 最后,在mapper文件中定义对应的
resultMap
。
<resultMap id="studentMap" type="Student">
<id property="id" column="student_id"/>
<result property="name" column="student_name"/>
<association property="classInfo" column="class_id" javaType="Class">
<id property="id" column="class_id"/>
<result property="name" column="class_name"/>
<result property="address" column="class_address"/>
</association>
</resultMap>
在这个resultMap
中,我们使用了association
关键字,表示关联的对象类型为Class
。在association
节点中,使用了id
、result
关键字,分别映射了对应的属性。
- 编写
StudentMapper.java
。
public interface StudentMapper {
Student getStudentById(int id);
}
- 在
MybatisTest
中执行查询操作。
public class MybatisTest {
public static void main(String[] args) {
String config = "mybatis-config.xml";
try (InputStream inputStream = Resources.getResourceAsStream(config)) {
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlSessionFactory = builder.build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
Student student = mapper.getStudentById(1);
System.out.println(student);
} catch (IOException e) {
System.err.println(e.getMessage());
}
}
}
运行结果:
{id=1, name='张三', classInfo=Class{id=1, name='一班', address='杭州'}}
3.4 示例2
下面,我们再来一个示例,展示实现多表关联查询的更多特性。在这个示例中,我们将查询“商品”表和“订单”表,返回商品名称、订单编号、商品数量和订单日期。
- 定义
Goods
类和Order
类。
public class Goods {
private int id;
private String name;
private double price;
// getter/setter
}
public class Order {
private int id;
private int goodsId;
private int quantity;
private Date date;
// getter/setter
}
- 添加
Mapper.xml
。
<select id="getOrderDetail" resultMap="orderMap">
SELECT
goods.name AS goods_name,
order.id AS order_id,
order.quantity,
order.date
FROM order
JOIN goods ON order.goods_id = goods.id
WHERE order.id = #{id}
</select>
其中的resultMap
如下:
<resultMap id="orderMap" type="Order">
<id property="id" column="order_id"/>
<result property="quantity" column="quantity"/>
<result property="date" column="date"/>
<association property="goods" column="goods_id" javaType="Goods">
<id property="id" column="id"/>
<result property="name" column="goods_name"/>
<result property="price" column="price"/>
</association>
</resultMap>
- 定义
OrderMapper
接口。
public interface OrderMapper {
Order getOrderDetail(int id);
}
- 编写测试代码。
public class MybatisTest {
public static void main(String[] args) {
String config = "mybatis-config.xml";
try (InputStream inputStream = Resources.getResourceAsStream(config)) {
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlSessionFactory = builder.build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
OrderMapper mapper = sqlSession.getMapper(OrderMapper.class);
Order order = mapper.getOrderDetail(1);
System.out.println(order);
} catch (IOException e) {
System.err.println(e.getMessage());
}
}
}
这个示例中,我们首先定义了Goods
类和Order
类,然后在order
表和goods
表之间建立多表关联查询。最后,我们通过定义OrderMapper
接口实现多表关联查询的操作。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Mybatis多表关联查询的实现(DEMO) - Python技术站