1、多对一的概念
-
多个学生,对应一个老师
-
对于学生而言,多个学生关联一个老师 (关联)【多对一】
-
对于老师而言,一个老师有多个学生(集合)【一对多】
2、搭建数据库
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');
3、搭建项目环境
-
编写实体类
学生类Student
public class Student { private Integer id; private String name; //多个学生可以是同一个老师,即多对一 private Teacher teacher; // 构造器 // toString // getter and setter }
老师类Teacher
public class Teacher { private Integer id; private String name; // 构造器 // toString // getter and setter }
-
编写实体类对应的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="com.jh.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="com.jh.mapper.TeacherMapper"> </mapper>
-
在核心配置文件中注册xml文件
<mappers> <mapper class="com.jh.mapper.TeacherMapper"/> <mapper class="com.jh.mapper.StudentMapper"/> </mappers>
4、按照查询嵌套处理
需求:获取所有学生及对应老师的信息
思路:
- 查询所有的学生信息
- 根据学生信息中的老师tid,查询对应的老师信息
- 返回值中包含了teacher的消息resultType不可用,怎么解决?
- 使用结果集映射:resultMap
- resultMap的type是Student
- student中的属性为teacher,对应数据库中为tid
- 使用association实现复杂类型的关联,处理关联查询
具体实现:
-
编写mapper接口方法
public interface StudentMapper { List<Student> getStudentList(); }
-
编写xml配置文件
<select id="getStudentList" resultMap="studentTeacher"> select * from student; </select> <resultMap id="studentTeacher" type="com.jh.domain.Student"> <!--association关联属性 property属性名 javaType属性类型 column在多的一方的表中的列名--> <association property="teacher" column="tid" javaType="com.jh.domain.Teacher" select="getTeacher"/> </resultMap> <!-- 这里传递过来的id,只有一个属性的时候,下面可以写任何值 association中column多参数配置: column="{key=value,key=value}" 其实就是键值对的形式,key是传给下个sql的取值名称,value是片段一中sql查询的字段名。 --> <select id="getTeacher" resultType="com.jh.domain.Teacher"> select * from teacher where id = #{id}; </select>
-
编写测试
测试结果如下
Student{id=1, name='小明', teacher=Teacher{id=1, name='廖老师'}} Student{id=2, name='小红', teacher=Teacher{id=1, name='廖老师'}} Student{id=3, name='小张', teacher=Teacher{id=1, name='廖老师'}} Student{id=4, name='小李', teacher=Teacher{id=1, name='廖老师'}} Student{id=5, name='小王', teacher=Teacher{id=1, name='廖老师'}}
5、按照结果嵌套处理
除了上面这种方式,我们还可以按照结果进行嵌套处理;
-
编写mapper接口
public interface StudentMapper { List<Student> getStudentList(); }
-
编写xml配置文件
<!-- 按照结果嵌套处理 --> <select id="getStudentList" resultMap="StudentTeacher"> select s.id sid, s.name sname, t.id tid, t.name tname from mybatis.student s, mybatis.teacher t where s.id = t.id; </select> <resultMap id="StudentTeacher" type="com.jh.domain.Student"> <id property="id" column="sid"/> <result property="name" column="sname"/> <!-- 关联对象property关联对象在Student实体类中的属性 --> <association property="teacher" javaType="com.jh.domain.Teacher"> <result column="tname" property="name"/> <result column="tid" property="id"/> </association> </resultMap>
-
测试结果
Student{id=1, name='小明', teacher=Teacher{id=1, name='廖老师'}} Student{id=2, name='小红', teacher=Teacher{id=1, name='廖老师'}} Student{id=3, name='小张', teacher=Teacher{id=1, name='廖老师'}} Student{id=4, name='小李', teacher=Teacher{id=1, name='廖老师'}} Student{id=5, name='小王', teacher=Teacher{id=1, name='廖老师'}}
总结:
- 按照查询进行嵌套处理就像SQL中的子查询
- 按照结果进行嵌套处理就像SQL中的联表查询