十二、延迟加载

1.使用场景

一对一、一对多、多对一、多对多
例如:一对一:学生、学生证,一对多:班级——学生
如果不采用延迟加载(立即加载),查询时会将一和多都查询,班级、班级中的所有学生
如果想要暂时只查询一的一方,而多的一方先不查询,而是在需要的时候再去查询,就要用到延迟加载

2.一对一

(1)conf.xml

<settings>
	<!-- 开启日志,并指定使用的具体日志 -->
	<setting name="logImpl" value="LOG4J"/>
		
	<!-- 开启延迟加载 -->
	<setting name="lazyLoadingEnabled" value="true"/>
		
	<!-- 关闭立即加载 -->
	<setting name="aggressiveLazyLoading" value="false"/>
</settings>

<mappers>
    <!--如果增加了mapper.xml,要修改conf.xml配置文件(将新增的mapper.xml加载进去)-->
	<mapper resource="nuc/hzb/mapper/studentMapper.xml" />
	<mapper resource="nuc/hzb/mapper/studentCardMapper.xml" />
</mappers>

(2)studentMapper.xml

<resultMap type="student" id="student_studentcard_lazy">
	<id property="stuNo" column="stuno"/>
	<result property="stuName" column="stuname"/>
	<result property="stuAge" column="stuage"/>	
	<!-- 学生证,通过select在需要的时候再查学生证 -->
	<association property="studentCard" javaType="StudentCard" select="nuc.hzb.mapper.StudentCardMapper.queryCardById"  column="cardid">
	<!-- 
		一对一时,对象成员使用association映射;javaType指定该属性的类型
		此次采用延迟加载:在查询学生时,并不立即加载学生证信息
	-->
	</association>
</resultMap>
 	
<select id="queryWithStudentWithOOLazy" resultMap="student_studentcard_lazy">
 	select * from student
</select>

(3)studentCardMapper.xml

<mapper namespace="nuc.hzb.mapper.StudentCardMapper">
	<!-- 查询学生证信息 -->	
	<select id="queryCardById" parameterType="int" resultType="studentCard">
		<!-- 查询学生对应的学生证 -->
		select * from studentCard where cardid = #{cardId}
	</select>
	<!-- 根据cardid查询学生证的SQL:nuc.hzb.mapper.StudentCardMapper.queryCardById-->	
</mapper>

(4)studentMapper.java

List<Student> queryWithStudentWithOOLazy();

(5)测试类

public static void queryWithStudentWithOOLazy() throws IOException {
	Reader reader = Resources.getResourceAsReader("conf.xml") ;
	SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
	SqlSession session = sessionFactory.openSession();
	studentMapper studentmapper = session.getMapper(studentMapper.class);
    // 在该处打断点,debug
	List<Student> students = studentmapper.queryWithStudentWithOOLazy();
	for(Student student : students) {		
		System.out.println(student.getStuNo() + "," + student.getStuName() + "," + student.getStuAge());	
		System.out.println(student.getStudentCard());	
	}
	session.close();
}

通过debug可以发现, 如果程序只需要学生,则只向数据库发送了查询学生的SQL
当我们后续需要用到学生证的时候,再第二次发送查询学生证的SQL

3.一对多

和一对一的延迟加载配置方法相同

(1)conf.xml

<settings>
	<!-- 开启日志,并指定使用的具体日志 -->
	<setting name="logImpl" value="LOG4J"/>
		
	<!-- 开启延迟加载 -->
	<setting name="lazyLoadingEnabled" value="true"/>
		
	<!-- 关闭立即加载 -->
	<setting name="aggressiveLazyLoading" value="false"/>
</settings>

<mappers>
    <!--如果增加了mapper.xml,要修改conf.xml配置文件(将新增的mapper.xml加载进去)-->
	<mapper resource="nuc/hzb/mapper/studentMapper.xml" />
	<mapper resource="nuc/hzb/mapper/studentCardMapper.xml" />
    <mapper resource="nuc/hzb/mapper/studentClassMapper.xml" />
</mappers>

(2)studentClassMapper.xml

<!-- 类-表的对应关系 -->
<resultMap type="studentClass" id="class_student_lazyLoad_map">
	<!-- 因为 type的主类是班级,因此先配置班级的信息-->
	<id  property="classId" column="classId"/>
	<result  property="className" column="className"/>
	<!-- 配置成员属性学生,一对多;属性类型:javaType,属性的元素类型ofType -->
	<!-- 再查班级对应的学生 -->
	<collection property="students" ofType="student" select="nuc.hzb.mapper.studentMapper.queryStudentsByClassId" column="classid">
	</collection>
</resultMap>	

<!-- 一对多,带延迟加载 -->
<select id="queryClassAndStudents" resultMap="class_student_lazyLoad_map">
<!--先查询班级 -->
	select  c.* from studentclass c
</select>

(3)studentMapper.xml

<select id="queryStudentsByClassId" parameterType="int" resultType="student">
 	select * from student where classid = #{classid}
</select>	

(4)studentClassMapper.java

List<StudentClass> queryClassAndStudents();

(5)测试类

// 查询班级和班级对应的学生,一对多(延迟加载)
public static void  queryClassAndStudents() throws IOException {
	Reader reader = Resources.getResourceAsReader("conf.xml") ;
	SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
	SqlSession session = sessionFactory.openSession();
	studentClassMapper studentmapper = session.getMapper(studentClassMapper.class);	
	List<StudentClass> studentClassList  = studentmapper.queryClassAndStudents();
	for(StudentClass studentClass : studentClassList) {
		System.out.println(studentClass.getClassId() + studentClass.getClassName());	
        
		for (Student student : studentClass.getStudents()) {
			System.out.println(student);
		}
	}
	session.close();
}

4.延迟加载的步骤

(1)开启延迟加载

配置conf.xml,通过settings标签

(2)配置mapper.xml

需要两个mapper.xml映射文件

学生、学生证

班级、学生

(3)例如

先查班级再查学生

查询班级通过resultMap标签去配置映射关系

查询学生的sql是通过select属性指定,并且通过column指定外键

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值