一. 多对一
1. 说明
- 多个学生,对应一个老师
- 对于学生这边而言, 关联 … 多个学生,关联一个老师 【多对一】
- 对于老师而言, 集合 , 一个老师,有很多学生 【一对多】
2. 案例
1. 数据表准备
-
Student表
CREATE TABLE `student` ( `id` int(10) NOT NULL, `name` varchar(30) DEFAULT NULL, `tid` int(10) DEFAULT NULL, PRIMARY KEY (`id`), KEY `fktid` (`tid`), CONSTRAINT `fktid` FOREIGN KEY (`tid`) REFERENCES `teacher` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-
Teacher表
CREATE TABLE `teacher` ( `id` int(10) NOT NULL, `name` varchar(30) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
2. 环境搭建
-
根据数据表字段创建实体类
public class Student { private int id; private String name; private Teacher teacher; } public class Teacher { private int id; private String name; }
-
创建Mapper接口
-
创建Mapper.xml文件
-
在核心配置文件中绑定Mapper接口或Mapper.xml文件
3. 按照查询嵌套处理(子查询)
1. 思路
- 查询出所有的学生信息
- 根据查询出来的学生的tid, 寻找对应的老师 -> 子查询
2. 步骤
-
第一步: 查询出所有的学生信息, 返回值类型为StudentTeacher
<select id="getStudents" resultMap="StudentTeacher"> select * from student </select>
-
第二步: 通过id查询出对应的老师信息
<select id="getTeacher" resultType="teacher"> select * from teacher where id = #{id} </select>
-
第三步: 关联
<resultMap id="StudentTeacher" type="Student"> <!--实体类属性对应数据库中的字段--> <result property="id" column="id"/> <result property="name" column="name"/> <!-- Student表中的teacher对应数据库中的tid字段 因为是复杂的属性, 所以通过javaType指定属性的类型 然后再通过调用getTeacher方法嵌套查询出Teacher --> <!--association: 关联--> <association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/> </resultMap>
4. 按照结果嵌套处理(联表查询)
- 代码
<resultMap id="StudentTeacher2" type="student"> <result property="id" column="sid" /> <result property="name" column="sname" /> <association property="teacher" javaType="Teacher"> <result property="name" column="tname" /> </association> </resultMap> <!--通过一个标签实现--> <select id="getStudents2" resultMap="StudentTeacher2"> select s.id sid, s.name sname, t.name tname from student s, teacher t where s.tid = t.id; </select>
二. 一对多
1. 实体类
-
Student
public class Student { private int id; private String name; private int tid; }
-
Teacher
public class Teacher { private int id; private String name; /** * 一个老师拥有多个学生 */ private List<Student> students; }
2. 按照查询嵌套处理(子查询)
-
第一步: 查询指定ID的teacher
<select id="getTeacher2" resultMap="TeacherStudent2"> select * from teacher where id = #{tid} </select>
-
第二步: 通过tid查询Student
<select id="getStudentByTid" resultType="Student"> select * from student where tid = #{tid} </select>
-
第三步: 关联
<resultMap id="TeacherStudent2" type="teacher"> <collection property="students" javaType="ArrayList" ofType="Student" select="getStudentByTid" column="id" /> </resultMap>
3. 按照结果嵌套处理(联表查询)
- 代码
<!--按结果嵌套查询 --> <resultMap id="TeacherStudent" type="teacher"> <result property="id" column="tid"/> <result property="name" column="tname"/> <!-- association 对象; collection 集合 javaType: 指定属性类型 集合中的泛型信息, 我们使用ofType获取 --> <collection property="students" ofType="Student"> <result property="id" column="sid"/> <result property="name" column="sname"/> <result property="tid" column="tid"/> </collection> </resultMap> <select id="getTeacher" resultMap="TeacherStudent"> select s.id sid, s.name sname, t.name tname, t.id tid from student s, teacher t where s.tid = t.id and t.id = #{tid}; </select>
三. 小结
- 关联 - association 【多对一】
- 集合 - collection 【一对多】
- javaType & ofType
- JavaType 用来指定实体类中属性的类型
- ofType 用来指定映射到List或者集合中的 pojo类型,泛型中的约束类型!
说明:
- 本文参考了狂神的Mybatis的课件
- 课程链接