MyBatis 学习笔记 第五章 延迟加载
延迟加载也叫懒加载,惰性加载,使用延迟加载可以提高程序的运行效率,针对持久层的操作,在某些特定的情况下去访问特定的数据库,在其他情况下可以不访问某些表,从一定程度上减少了Java应用与数据库的交互次数。
查询学生和班级的时候,学生和班级在两张表中,如果当前需求只需要获取学生的信息,那么查询学生单表即可,如果需要通过学生查询对应的班级信息,则必须查询两张表,不同的业务需求,需要查询不同的表,根据具体的业务需求来动态减少数据表查询的的工作就是延迟加载。
- 在配置mybatis-config.xml中开启延迟加载
<settings>
<!--打印SQL-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
<!--开启延迟加载-->
<setting name="lazyLoadingEnabled" value="true"/>
</settings>
- 将多表关联查询拆分成多个单表查询
StudentRepository.java:
public Student findByIdLazy(long id);
StudentMapper.xml:
<resultMap id="studentMapLazy" type="com.fw.entity.Student">
<id column="sid" property="sid"></id>
<result column="sname" property="sname"></result>
<association property="classes" javaType="com.fw.entity.Classes" select="com.fw.repository.ClassesRepository.findByIdLazy" column="cid"></association>
</resultMap>
<select id="findByIdLazy" parameterType="long" resultMap="studentMapLazy">
select * from student where sid = #{sid}
</select>
ClassesRepository.java:
public Classes findByIdLazy(long id);
ClassesMapper.xml:
<select id="findByIdLazy" parameterType="long" resultType="com.fw.entity.Classes">
select * from classes where cid =#{cid}
</select>
测试1(根据学生id查询所在班级名):
// 查询
Student student = studentRepository.findByIdLazy(1011L);
System.out.println(student.getClasses().getCname());
控制台log:
Logging initialized using 'class org.apache.ibatis.logging.stdout.StdOutImpl' adapter.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
Opening JDBC Connection
Created connection 902478634.
Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@35cabb2a]
==> Preparing: select * from student where sid = ?
==> Parameters: 1011(Long)
<== Columns: sid, sname, cid
<== Row: 1011, 张三, 101
<== Total: 1
==> Preparing: select * from classes where cid =?
==> Parameters: 101(Long)
<== Columns: cid, cname
<== Row: 101, 一班
<== Total: 1
一班
Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@35cabb2a]
Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@35cabb2a]
Returned connection 902478634 to pool.
测试2(根据学生id查询学生姓名):
// 查询
Student student = studentRepository.findByIdLazy(1011L);
System.out.println(student.getSname());
控制台log:
Logging initialized using 'class org.apache.ibatis.logging.stdout.StdOutImpl' adapter.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
Opening JDBC Connection
Created connection 902478634.
Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@35cabb2a]
==> Preparing: select * from student where sid = ?
==> Parameters: 1011(Long)
<== Columns: sid, sname, cid
<== Row: 1011, 张三, 101
<== Total: 1
张三
Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@35cabb2a]
Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@35cabb2a]
Returned connection 902478634 to pool.
测试1查询班级名,执行了两次SQL查询(根据学生id查询所在班级id,根据班级id查询班级名);
测试2查询学生名,执行了1次SQL查询(根据学生id查询学生名)。