在mybaits中,可以很好地显示对象数据,如果说是一个普通对象,直接可以很简单的写好对应关系,然后获取数据
但是,如果对象中的属性是另一个对象呢,甚至是一个collection(list/set/array)呢?
一般的写法是,在写几个sql,通过级联进行关联,用第一个sql的查询结果做条件,接着进行查询
但是在我眼中这样有问题:
- 会进行多次连接数据库,数据库连接池可以解决这个问题;
- 另外会打印多条sql,不便于分析;
- 多个select语句,不便于维护;
如何解决呢,我们有另外一种解决办法,那就是用一条sql,查出所有的数据
测试数据结构:
public class StudentClass { // 学生班级
private String classId;
private String className;
private Teacher teacher;
private List<Student> studentList;
public static class Student { // 学生
private String strudentId;
private String studentName;
}
public static class Teacher { // 教师
private String teacherId;
private String teacherName;
}
}
上面的这个对象,就是测试对象,班级中有一个教师跟多个学生。
那么在mybatis中,可以这么写
<!--主表-班级表-->
<resultMap id="classMap" type="test.StudentClass">
<result column="classId" property="classId" />
<result column="className" property="className" />
<association property="teacher" columnPrefix="teacher_" resultMap="teacherMap"/>
<collection property="studentList" javaType="ArrayList" ofType="test.StudentClass$Student" resultMap="studentMap" columnPrefix="student_"/>
</resultMap>
<!--从表-教师表-->
<resultMap id="teacherMap" type="test.StudentClass$Teacher">
<result column="teacherId" property="teacherId" />
<result column="teacherName" property="teacherName" />
</resultMap>
<!--从表-学生表-->
<resultMap id="studentMap" type="test.StudentClass$Student">
<result column="studentId" property="studentId" />
<result column="studentName" property="studentName" />
</resultMap>
<select id="selectStudentClass" resultMap="classMap">
select
classId,
className,
teacherId teacher_teacherId,
teacherName teacher_teacherName,
studentId student_studentId,
studentName student_studentName
from t_class
inner join t_student on t_class.classId = t_student.classId
<!--进行表之间的关联、分组等-->
</select>
- 代码中一共有3个resultMap,分别是,班级studentClass,学生student,教师teacher,其他的属性正常处理就行。他们之间有从属关系,班级包含教师跟学生,这个在xml代码中也有体现
- 一对一用“association”进行关联
- 一对多用“collection”进行关联
- columnPrefix="teacher_",这个参数的作用就是,告诉mybatis,只要这个前缀的属性名,就跟对应的resultMap进行关联
- ofType="test.StudentClass$Student",这个参数的作用是,限制list中的对象类型
- type="test.StudentClass$Teacher",因为样例使用的是静态内部类,所以调用静态内部类,需要这么写,当然你也可以不用静态内部类