1. 多对一
什么是多对一呢?
- 多个学生对应一个老师
1.1 数据库设计
CREATE TABLE `teacher` (
`id` INT(10) NOT NULL,
`name` VARCHAR(30) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;
INSERT INTO teacher(`id`, `name`) VALUES (1, '张三');
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;
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('1', '小明', '1');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('2', '小红', '1');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('3', '小张', '1');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('4', '小李', '1');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('5', '小王', '1');
1.2 搭建测试环境
-
编写实体类POJO
public class Teacher { private int id; private String name; // 无参构造 // 有参构造 // get、set方法 // toString方法 }
public class Student { private int id; private String name; //多个学生可以是同一个老师,即多对一 private Teacher teacher; // 无参构造 // 有参构造 // get、set方法 // toString方法 }
-
编写实体类对应的Mapper接口
public interface StudentMapper { }
public interface TeacherMapper { }
-
编写接口对应的mapper.xml配置文件
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="top.linzeliang.mapper.StudentMapper"> </mapper>
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="top.linzeliang.mapper.TeacherMapper"> </mapper>
1.3 按查询嵌套处理
-
给StudentMapper增加方法
//获取所有学生及对应老师的信息 public List<Student> getStudents();
-
编写对应的Mapper文件
<!-- 需求:获取所有学生及对应老师的信息 思路: 1. 获取所有学生的信息 2. 根据获取的学生信息的老师ID->获取该老师的信息 3. 思考问题,这样学生的结果集中应该包含老师,该如何处理呢,数据库中我们一般使用关联查询? 1. 做一个结果集映射:StudentTeacher 2. StudentTeacher结果集的类型为 Student 3. 学生中老师的属性为teacher,对应数据库中为tid。 多个 [1,...)学生关联一个老师=> 一对一,一对多 4. 查看官网找到:association – 一个复杂类型的关联;使用它来处理关联查询--><select id="getStudents" resultMap="StudentMap"> select * from student;</select><resultMap id="StudentMap" type="student"> <association property="teacher" column="tid" javaType="teacher" select="getTeacher"/></resultMap><!-- 这里传递过来的id,只有一个属性的时候,下面可以写任何值 association中column多参数配置: column="{key=value,key=value}" 其实就是键值对的形式,key是传给下个sql的取值名称,value是片段一中sql查询的字段名。--><select id="getTeacher" resultType="Teacher"> select * from teacher where id = #{tid};</select>
-
进行测试
1.4 按结果嵌套处理
个人认为这种容易理解一些
-
接口方法编写
//获取所有学生及对应老师的信息public List<Student> getStudents();
-
编写对应的mapper配置文件
<select id="getStudents" resultMap="StudentMap"> select t1.id id, t1.name sname, t2.id tid, t2.name tname from student t1, teacher t2 where t1.tid = t2.id;</select><resultMap id="StudentMap" type="student"> <id property="id" column="id"/> <result property="name" column="sname"/> <association property="teacher" javaType="Teacher"> <id property="id" column="tid"/> <result property="name" column="tname"/> </association></resultMap>
-
进行测试
2. 一对多
- 一个老师对应多个学生
2.1 搭建测试环境
-
实体类的编写
public class Student { private int id; private String name; private int tid; // 无参构造 // 有参构造 // get、set方法 // toString方法}
public class Teacher { private int id; private String name; //一个老师多个学生 private List<Student> students; // 无参构造 // 有参构造 // get、set方法 // toString方法}
2.2 按查询嵌套处理
-
TeacherMapper接口编写方法
//获取指定老师,及老师下的所有学生public Teacher getTeacher(int id);
-
编写接口对应的Mapper配置文件(多了ofType的这个属性)
<select id="getTeacher" resultMap="TeacherMap"> select * from teacher where id = #{id};</select><resultMap id="TeacherMap" type="Teacher"> <id property="id" column="id"/> <result property="name" column="name"/> <!-- column是一对多的外键 , 写的是一的主键的列名 --> <collection property="students" column="id" javaType="ArrayList" ofType="Student" select="getStudent"/></resultMap><select id="getStudent" resultType="Student"> select * from student where tid = #{id}</select>
-
进行测试
2.3 按结果嵌套处理
-
TeacherMapper编写方法
//获取指定老师,及老师下的所有学生public Teacher getTeacher(int id);
-
编写接口对应的Mapper配置文件
<select id="getTeacher" resultMap="TeacherMap"> select t1.id tid, t1.name tname, t2.id sid, t2.name sname from teacher t1, student t2 where t1.id = t2.tid and t1.id = #{id};</select><resultMap id="TeacherMap" type="Teacher"> <id property="id" column="tid"/> <result property="name" column="tname"/> <collection property="students" ofType="Student"> <id property="id" column="sid"/> <result property="name" column="sname"/> <result property="tid" column="tid"/> </collection></resultMap>
-
进行测试
3. ResultMap总结
- 如果属性是JavaBean对象,则使用关联(association),
- 如果属性是集合,则使用集合(collection)
- 则association是用于一对一和多对一;collecion适用于一对多的关系
- javaType和ofType都是用于指定对象类型的
- javaType是用来指定pojo中属性的类型
- ofType指的是映射到list集合属性中的pojo的类型