Mybatis级联
在客观世界中,对象很少是孤独存在的,如班级与学生之间的关系,它们的实例之间可以互相访问,这就是关联关系。那么映射到数据库中就是表与表之间的关联关系(级联),数据库中表常见的关联关系一般有三种:
1、一对一:一个班主任只属于一个班级,一个班级也只能有一个班主任
2、一对多:一个班级有多个学生,一个学生只属于一个班级
3、多对多:一个学生可以选多门课,一门课可以有多个学生选
一般来说使用级联可以帮我们十分便捷的获取数据,但是级联并不是必须的,过多的级联会增加系统的复杂度,降低系统的性能,所以当级联超过3层时,就不要考虑使用级联了,这样会导致多个对象的关联,使得系统的耦合性增高,变的复杂难以维护。在实际开发中我们需要根据实际情况来考虑是否使用级联。
在Mybatis中关联关系也是分为为三种:一对一关系,一对多关系,以及鉴别器(根据某些条件来决定采用具体级联的方案,可以自行了解)。需要注意的是在Mybatis中并没有多对多的关联关系,因为多对多的关系太过复杂了,使用起来比较困难,我们可以使用两个一对多来进行替换,所以Mybatis不再支持多对多的关联关系。
这里我们分别先创建 班主任,班级 和 学生这三张表:
班主任表 :
CREATE TABLE head_teacher( teacher_id INT(11) PRIMARY KEY, teacher_name VARCHAR(20), age INT(3) );
班级表:
CREATE TABLE class( class_id INT(11) PRIMARY KEY, class_name VARCHAR(20), teacher_id INT(11) );
学生表:
CREATE TABLE student( student_id INT(11) PRIMARY KEY, student_name VARCHAR(20), gender VARCHAR(3), age INT(3), class_id INT(11) );
一对一关系处理:
Mybatis给出关联关系的解决方案就是resultMap:
<resultMap id="classInfo" type="entity.TClass"> <id property="classId" column="class_id"/> <result property="className" column="class_name"/> <!-- association 元素实现一对一级联, property="teacher" 指定TClass类中相应的字段名, javaType 指定类型 --> <association property="teacher" javaType="entity.HeadTeacher"> <id property="teacherId" column="teacher_id" /> <result property="name" column="teacher_name" /> <result property="age" column="age" /> </association> </resultMap>
然后返回类型使用ResultMap即可:
<select id="getClassById" parameterType="Integer" resultMap ="classInfo"> SELECT c.*,t.* FROM t_class c , head_teacher t WHERE c.teacher_id=t.teacher_id AND c.class_id=#{id} </select>
如果想要提高复用性,也可以将Teacher类型单独封装到resultMap 中,然后在association标签中通过 resultMap 属性引入即可:
<association property="teacher" resultMap="headTeacherInfo"/>
一对多关系处理:
MyBatis 一对多关联关系:比如一个班级可以对应多个学生,现有需求根据班级的id查出当前班级信息和该班级的所有学生
<resultMap id="classInfo2" type="entity.TClass1"> <id property="classId" column="class_id"/> <result property="className" column="class_name"/> <!-- 一对多关联映射:collection --> <collection property="students" ofType="entity.Student"> <id property="studentId" column="student_id" /> <result property="studentName" column="student_name" /> <result property="gender" column="gender" /> <result property="age" column="age" /> </collection> </resultMap>
<select id="findTClass1ById" parameterType="Integer" resultMap="classInfo2"> SELECT c.*,s.* FROM t_class c , student s WHERE c.class_id=s.class_id AND c.class_id=#{id} </select>
多对多关系处理:
引入中间表,将其转化成两个一对多处理。