目录
十二、MyBatis的高级映射及延迟加载
12.1多对一
级联属性映射
association
分步查询
12.2多对一延迟加载
12.3一对多
collection
分步查询
12.4一对多延迟加载
十二、MyBatis的高级映射及延迟加载
12.1多对一
-
多种方式,常见的三种方式:
-
第一种方式:一条SQL语句,级联属性映射。
-
第二种方式:一条SQL语句,association。
-
第三种方式:两条SQL语句,分布查询(常用)。
-
优点:可复用、支持懒加载。
-
-
级联属性映射
-
pojo类Student种添加一个属性:Clazz clazz;表示学生关联的班级对象。
public class Student {
private Integer sid;
private String sname;
private Clazz clazz;
}
StudentMapper
/**
* 根据id获取学生信息。同时获取学生关联的班级信息。
* @param id 学生的id
* @return 学生对象,但是学生对象当中含有班级对象。
*/
Student selectById(Integer id);
StudentMapper.xml
<resultMap id="studentResultMap" type="Student">
<id property="sid" column="sid"/>
<result property="sname" column="sname"/>
<result property="clazz.cid" column="cid"/>
<result property="clazz.cname" column="cname"/>
</resultMap>
<select id="selectById" resultMap="studentResultMap">
select s.sid,
s.sname,
c.cid,
c.cname
from t_stu s
left join t_clazz c on s.cid = c.cid
where s.sid = #{sid}
</select>
association
-
其它位置都不需要改,只需要修改resultMap中的配置:association即可。
StudentMapper.xml
<resultMap id="studentResultMapAssociation" type="Student">
<id property="sid" column="sid"/>
<result property="sname" column="sname"/>
<association property="clazz" javaType="Clazz">
<id property="cid" column="cid"/>
<result property="cname" column="cname"/>
</association>
</resultMap>
<select id="selectByIdAssociation" resultMap="studentResultMapAssociation">
select s.sid, s.sname, c.cid, c.cname
from t_stu s
left join t_clazz c on s.cid = c.cid
where s.sid = #{sid}
</select>
-
学生对象关联一个班级对象。
-
property:提供要映射的POJO类的属性名。
-
javaType:用来指定要映射的java类型
分步查询
StudentMapper
Student selectByIdStep1(Integer sid);
StudentMapper.xml
<resultMap id="studentResultMapByStep" type="Student">
<id property="sid" column="sid"/>
<result property="sname" column="sname"/>
<association property="clazz" column="cid" select="com.hhb.mapper.ClazzMapper.selectByIdStep2"/>
</resultMap>
<select id="selectByIdStep1" resultMap="studentResultMapByStep">
select sid, sname, cid
from t_stu
where sid = #{sid};
</select>
-
association中select位置填写sqlId。sqlId=namespace+id。
ClazzMapper
Clazz selectByIdStep2(Integer cid);
ClazzMapper.xml
<select id="selectByIdStep2" resultType="Clazz">
select cid, cname
from t_clazz
where cid = #{cid};
</select>
-
分步优点:
-
代码复用性增强:大步骤拆分成多个小步骤,每一个小步骤可以重复利用。
-
支持延迟加载(懒加载):暂时访问不到的数据可以先不查询,提高程序的执行效率。
-
12.2多对一延迟加载
-
要想支持延迟加载,只需要在association标签中添加fetchType="lazy"即可。
-
默认情况下是没有开启延迟加载的,需要手动设置。
StudentMapper.xml
<resultMap id="studentResultMapByStep" type="Student">
<id property="sid" column="sid"/>
<result property="sname" column="sname"/>
<association property="clazz" column="cid" select="com.hhb.mapper.ClazzMapper.selectByIdStep2" fetchType="lazy"/>
</resultMap>
-
在实际开发中,大部分都是需要延迟加载的,所以建议开启全部的延迟加载机制。在myabtis核心配置文件中配置如下:
<settings>
<setting name="lazyLoadingEnabled" value="true"/>
</settings>
-
如果某一项不需要使用延迟加载,在不需要的association标签中设置fetchType="eager".
12.3一对多
-
一对多的实现通常是在一的一方有List集合属性。
在Clazz类中添加List<Student> stus; 属性。
public class Clazz {
private Integer cid;
private String cname;
private List<Student> stus;
// set get⽅法
// 构造⽅法
// toString⽅法
}
-
第一种方式:collection
-
第二种方式:分布查询
collection
ClazzMapper接口
Clazz selectByCollection(Integer cid);
ClazzMapper.xml
<resultMap id="clazzResultMap" type="Clazz">
<id property="cid" column="cid"/>
<result property="cname" column="cname"/>
<collection property="stus" ofType="Student">
<id property="sid" column="sid"/>
<result property="sname" column="sname"/>
</collection>
</resultMap>
<select id="selectByCollection" resultMap="clazzResultMap">
select c.cid, c.cname, s.sid, s.sname
from t_clazz c
left join t_stu s on c.cid = s.cid
where c.cid = #{cid};
</select>
-
一对多,这里是collection。
-
ofType 属性用来指定集合当中的元素类型。
ClazzMapperTest.testSelectByCollection
@Test
public void testSelectByCollection() {
SqlSession sqlSession = SqlSessionUtil.openSession();
ClazzMapper mapper = sqlSession.getMapper(ClazzMapper.class);
Clazz clazz = mapper.selectByCollection(1000);
System.out.println(clazz);
sqlSession.commit();
sqlSession.close();
}
分步查询
ClazzMapper接口
Clazz selectByStep1(Integer cid);
ClazzMapper.xml
<resultMap id="clazzResultMapStep" type="clazz">
<id property="cid" column="cid"/>
<result property="cname" column="cname"/>
<collection property="stus" column="cid" select="com.hhb.mapper.StudentMapper.selectByStep2" fetchType="lazy"/>
</resultMap>
<select id="selectByStep1" resultMap="clazzResultMapStep">
select cid, cname
from t_clazz
where cid = #{cid};
</select>
-
开启延迟加载。
StudentMapper接口
Student selectByStep2(Integer sid);
StudentMapper.xml
<select id="selectByStep2" resultType="student">
select sid, sname, cid
from t_stu
where sid = #{sid};
</select>
执行结果
12.4一对多延迟加载
-
一对多延迟加载机制和多对一是一样的。
-
第一种:fetchType="lazy"
-
第二种:修改全局的配置setting,lazyLoadingEnabled=true,如果开启全局延迟加载后想让某个sql不使用延迟加载:fetchType="eager"
-