场景
创建student表:1
2
3
4
5
6
7
8CREATE 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表:1
2
3
4
5CREATE TABLE `teacher` (
`id` INT(10) NOT NULL,
`name` VARCHAR(30) DEFAULT NULL,
PRIMARY KEY (`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8
要求
查询 学生学号,学生姓名,老师姓名
MySQL
1 | select s.id ,s.name ,t.name |
MyBatis实现
实体类(pojo)
Student.java:1
2
3
4
5
6public class Student {
private int id;
private String name;
private Teacher teacher;
<!-- getter,setter,toString -->
}
Q:为什么学生属性中用Teacher teacher而不是int tid?
A:如果写int tid就相当于写“死”了,没有达到学生和老师关联的效果。
Teacher.java:1
2
3
4
5public class Teacher {
private int id;
private String name;
<!-- getter,setter,toString -->
}
StudentMapper.xml
按照结果嵌套处理
1 | <select id="getStudent2" resultMap="StudentTeacher2"> |
思路就是先写好SQL语句,再用resultMap去解释里面的内容。
Student类中的属性id对应结果中的sid,属性name对应结果中的sname。
属性teacher由于是一个复杂属性,所以用association,这里有一种递进的感觉:第一层说明属性teacher的类型是Teacher,第二层说明teacher对象的name属性对应结果中的tname。
查询中子集有相同字段取出的数据就会有问题,因此要采用别名的形式。
子查询
先查询所有学生的信息,再根据查询出来的学生的tid,寻找对应的老师1
2
3
4
5
6
7
8
9
10
11
12
13
14<!-- 查询所有学生 -->
<select id="getStudent" resultMap="StudentTeacher">
select * from student;
</select>
<!-- 上下两个select中建立连接 -->
<resultMap id="StudentTeacher" type="Student">
<association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
</resultMap>
<!-- 根据id查询老师 -->
<select id="getTeacher" resultType="Teacher">
select * from teacher where id=#{tid};
</select>
复杂的属性(Teacher)需要单独处理,如果是一个对象就用 Association,此处为Teacher对象。
property=”teacher”:学生类里的属性叫teacher
column=”tid”:数据库里的字段叫tid
javaType=”Teacher”:因为属性是个复杂类型,所以要给它定义类型Teacher
select=”getTeacher”:嵌套查询,getTeacher为下面select的id
注意
ResultMap标签中的COLUMN字段对应的不是数据库表中的字段名,而是select语句返回的字段名,当字段有重复时应对其进行重命名