1.mybatis延迟加载策略
什么是延迟加载?
延迟加载就是在需要用到数据时才进行加载,不需要用到数据时就不加载数据。延迟加载也称懒加载.好处: 先从单表查询,需要时再从关联表去关联查询,大大提高数据库性能,因为查询单表要比关联查询多张表速度要快。
坏处: 因为只有当需要用到数据时,才会进行数据库查询,这样在大批量数据查询时,因为查询工作也要消耗时间,所以可能造成用户等待时间变长,造成用户体验下降。
开启懒加载
```
<settings>
<!-- 开启全局懒加载-->
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
```
### association延迟加载
1.在IScoreDao接口中增加
```
List<Score> findAllScoreWithStudentLazy();
```
2.在IScoreDao.xml 中增加
```
<!-- 定义封装StudentScore和user的resultMap -->
<resultMap id="findAllScoreWithStudentLazyMap" type="Score">
<id property="scoreid" column="scoreid"></id>
<result property="coursename" column="coursename"></result>
<result property="score" column="score"></result>
<!-- 一对一的关系映射:配置封装Student的内容-->
<association property="student" javaType="Student"
select="com.wgz.dao.IStudentDao.findStudentById" column="studentid" fetchType="lazy">
</association>
</resultMap>
<select id="findAllScoreWithStudentLazy" resultMap="findAllScoreWithStudentLazyMap">
select * from score_tb;
</select>
```
select:为我们调用其他映射的id
column:为传递的参数
javaType:为查询到的java 数据类型
fetchType:是否使用懒加载,如果不设置与全局设置保持一致
3.测试
```
IScoreDao scoreDao = sqlSession.getMapper(IScoreDao.class);
List<Score> scoreList = scoreDao.findAllScoreWithStudentLazy();
for (Score score:scoreList){
// 不调用学生相关信息,不请求查数据库
System.out.println("score:"+score.getScore());
// 调用学生信息,发起二次请求查询学生相关的数据库
//System.out.println("student:"+score.getStudent());
}
```
### collection延迟加载
1.在IStudentDao增加
```
/**
* 延迟加载学生的成绩
* @return
*/
List<Student> findAllStudentWithScoreListLazy();
```
2.在IStudentDao.xml 中增加
```
<!--
一对多懒加载
-->
<resultMap id="findAllStudentWithScoreListLazyMap" type="Student">
<id property="id" column="id"></id>
<result property="name" column="name"></result>
<result property="sex" column="name"></result>
<result property="age" column="age"></result>
<result property="height" column="height"></result>
<result property="birthday" column="birthday"></result>
<collection property="scoreList" column="id" select="com.wgz.dao.IScoreDao.findScoreByStudentId" fetchType="lazy">
</collection>
</resultMap>
<select id="findAllStudentWithScoreListLazy" resultMap="findAllStudentWithScoreListLazyMap">
select * from student_tb
</select>
```
3.测试
```
// 方式一 通过代理:
IStudentDao studentDao = sqlSession.getMapper(IStudentDao.class);
List<Student> studentList = studentDao.findAllStudentWithScoreListLazy();
for (Student student:studentList){
// 不调用学生成绩相关信息,不请求查数据库
System.out.println("Student:"+student.getName());
// 调用学生成绩信息,发起二次请求查询学生成绩相关的数据库
System.out.println("ScoreList:"+student.getScoreList());
}
```
**注意**
默认情况mybatis开延迟加载只要调用toString()方法包括Object的object的都会触发懒加载可以通过设置一下解决
```
<!--解决 懒加载时 打印对象toString 触发 懒加载
lazyLoadTriggerMethods:指定哪个对象的方法触发一次延迟加载。默认值:equals,clone,hashCode,toString
-->
<setting name="lazyLoadTriggerMethods" value="false"/>
```