文章目录
- 前言
- 多对一关联 association
- 一对多关联 collection
- resultMap元素
前言
提示:这里可以添加本文要记录的大概内容:
关联查询是指在一个查询中同时获取多个表中的数据,将它们结合在一起进行展示。
关联表需要两个及以上的表
数据库代码:
DROP TABLE IF EXISTS student;
DROP TABLE IF EXISTS teacher;
CREATE TABLE teacher
(
tid int PRIMARY KEY auto_increment,
tname VARCHAR(30)
);
CREATE TABLE student
(
sid int PRIMARY KEY auto_increment,
sname VARCHAR(30),
age int,
tid int,
foreign key (tid) references teacher(tid)
);
生成实体类代码:
Student :
public class Student {
private Integer sid;
private String sname;
private Integer age;
// 方便以后的扩展 po类
private Teacher teacher;
// 自动生成 Getter、Setter、toString()、有参无参方法
}
Teacher :
public class Teacher {
private Integer tid;
private String tname;
// 自动生成 Getter、Setter、toString()、有参无参方法
}
提示:以下是本篇文章正文内容,下面案例可供参考
- 主键列标记是
id
- 普通列标记是
result
- 关联查询的映射标记是
association
多对一关联 association
<association>
标签用于描述一个一对一的关联关系,它可以嵌套在<select>
语句中,查询指定的关联表数据。
多个学生关联一个老师
在 main/java 文件夹中创建学生和老师的接口以及同名的映射文件
其中映射文件中的namespace
是接口文件中的限定名
查询所有的学生数据,同时关联出对应的老师
所以在学生接口文件中:
public interface StudentMapper {
List<Student> queryAllStudents();
}
在学生的映射文件中:SQL语句用的SQL99写法
<mapper namespace="com.mybatis.mapper.StudentMapper">
<!-- 结果的映射 -->
<select id="queryAllStudents" resultMap="st">
select sid,sname,age,t.tid,tname
from student s join teacher t
on s.tid = t.tid
</select>
</mapper>
SQL语句写完后要在Navicat中单独运行一下:防止有错
因为 t.tid,tname 和 teacher 数据不一致,所有需要在映射文件中加一个 resultMap
标记
需要把不一致的那两列单独映射到 teacher 属性里
所以最终学生的映射文件中的代码:
<mapper namespace="com.mybatis.mapper.StudentMapper">
<!-- st:随便起名 -->
<resultMap type="Student" id="st">
<!-- 主键列用id标记 -->
<id column="sid" property="sid"/>
<!-- 普通列用result标记 -->
<result column="sname" property="sname"/>
<result column="age" property="age"/>
<!-- 关联查询的映射标记是association -->
<association property="teacher" javaType="Teacher">
<id column="tid" property="tid"/>
<result column="tname" property="tname"/>
</association>
</resultMap>
<!-- 结果的映射与上面的id值对应 -->
<select id="queryAllStudents" resultMap="st">
select sid,sname,age,t.tid,tname
from student s join teacher t
on s.tid = t.tid
</select>
</mapper>
测试类代码:
@Test
public void queryStudent() {
StudentMapper mapper = session.getMapper(StudentMapper.class);
List<Student> list = mapper.queryAllStudents();
// foreach提示
for (Student student : list) {
System.out.println(student);
}
}
一对多关联 collection
<collection>
标签用于描述一个一对多的关联关系,它可以嵌套在<select>
语句中,查询关联表数据集合。
一个老师关联多少个学生
查询老师数据时,同时关联出老师对应的学生
这里要更老师的 po 类,加上:
// 数组和集合能体现多个数据,这里用集合,因为不确定有多少学生
private List<Student> students;
// 生成Getter、Setter
所以在老师接口文件中:首先在接口中定义一个方法(查询所有老师)
List<Teacher> queryAllTeachers();
在老师的映射文件中:
首先加上 namespace,映射文件中的namespace
是接口文件中的限定名
<select id="queryAllTeachers">
select t.tid,tname,sid,sname,age
from teacher t join student s
on t.tid = s.tid
</select>
SQL语句写完后要在Navicat中单独运行一下:防止有错
接下来配置映射:
<!-- 结果映射 -->
<resultMap type="Teacher" id="teacher">
<id column="tid" property="tid"/>
<result column="tname" property="tname"/>
<!-- 一对多映射使用collection标记 --><!-- 属性名property是老师po类的students -->
<collection property="students" ofType="Student">
<id column="sid" property="sid"/>
<result column="sname" property="sname"/>
<result column="age" property="age"/>
</collection>
</resultMap>
最后要在 select 标签内加一个 resultMap
,因为结果是自己单独配置的
所以最终老师的映射文件中的代码:
<mapper namespace="com.mybatis.mapper.TeacherMapper">
<!-- 结果映射 -->
<resultMap type="Teacher" id="teacher">
<id column="tid" property="tid"/>
<result column="tname" property="tname"/>
<!-- 一对多映射使用collection标记 --><!-- 属性名property是老师po类的students -->
<collection property="students" ofType="Student">
<id column="sid" property="sid"/>
<result column="sname" property="sname"/>
<result column="age" property="age"/>
</collection>
</resultMap>
<select id="queryAllTeachers" resultMap="teacher">
select t.tid,tname,sid,sname,age
from teacher t join student s
on t.tid = s.tid
</select>
</mapper>
接下来写测试类
@Test
public void queryTeacher() {
TeacherMapper mapper = session.getMapper(TeacherMapper.class);
List<Teacher> list = mapper.queryAllTeachers();
// foreach循环
for (Teacher teacher : list) {
// 只输出老师数据
System.out.println(teacher);
// 得到学生
List<Student> sl = teacher.getStudents();
// 遍历sl学生集合,看看老师关联的学生数据
for (Student student : sl) {
System.out.println(student);
}
}
}
resultMap元素
当数据表中的列和需要返回的对象的属性不完全一致, MyBatis是不会自动赋值的。此时,就可以使用<resultMap>
元素进行处理。
<resultMap>
元素的子元素<id>
用于表示哪个列是主键,而<result>
元素用于表示POJO和数据表中普通列的映射关系。
<resultMap id="custResultMap" type="Customer">
<id property="id" column="id" />
<result property="custId" column="cust_id"/>
<result property="name" column="name"/>
</resultMap>