MyBatis:association

场景

创建student表:

1
2
3
4
5
6
7
8
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表:

1
2
3
4
5
CREATE TABLE `teacher` (
`id` INT(10) NOT NULL,
`name` VARCHAR(30) DEFAULT NULL,
PRIMARY KEY (`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8

要求

查询 学生学号,学生姓名,老师姓名

MySQL

1
2
3
select s.id ,s.name ,t.name
from student s,teacher t
where s.tid=t.id

MyBatis实现

实体类(pojo)

Student.java:

1
2
3
4
5
6
public 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
5
public class Teacher {
private int id;
private String name;
<!-- getter,setter,toString -->
}

StudentMapper.xml

按照结果嵌套处理

1
2
3
4
5
6
7
8
9
10
11
12
13
<select id="getStudent2" resultMap="StudentTeacher2">
select s.id sid,s.name sname,t.name tname
from student s, teacher t
where s.tid=t.id;
</select>

<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>

思路就是先写好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语句返回的字段名,当字段有重复时应对其进行重命名