MyBatis 最佳实践篇 3:关联查询懒加载
2019-04-11 本文已影响0人
兆雪儿
MyBatis 中联合查询可分为关联查询和关联结果两种方式(具体查看 Mybatis 文档篇 3.5:Mapper XML 之 Result Maps)。
对于关联查询方式,我们可以开启懒加载功能。所谓懒加载,即在使用的时候才加载,不使用不加载。这样可以避免当我们只需要其中的一点内容时,数据库返给我们一大堆我们不需要的结果。
开启懒加载,只需要在 mybatis-config.xml 中加入:
<settings>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
<setting name="proxyFactory" value="CGLIB"/>
</settings>
我们使用下面这个方法来进行测试。在方法的第 11 行 sleep 5 秒,在第 16 行获取关联的 posts:
public void testAssociationAndCollectionSelect() {
SqlSession session = FactoryBuildByXML.getFactory().openSession(true);
try {
BlogMapper blogMapper = session.getMapper(BlogMapper.class);
Blog blog = blogMapper.getBlogById3(1);
System.out.println(blog.soutBlog());
//配置文件开启懒加载后,此处停止 5 秒测试关联对象的懒加载
//只有在使用关联对象的时候,才会执行关联对象的查询语句(基于关联查询)
System.out.println("我要睡觉了zzz...");
long start = System.currentTimeMillis();
Thread.sleep(5000);
long end = System.currentTimeMillis();
System.out.println("我睡醒了!一共睡了 " + (end - start)/1000 + " 秒...");
//在这里开始获取 post 对象
List<Post> posts = blog.getPosts();
for (Post post : posts) {
System.out.println(post.toString());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
session.close();
}
}
执行的 sql 如下:
<resultMap id="blogResultMapSelect" type="Blog">
<id column="id" property="id"/>
<result column="name" property="name"/>
<!--column 为 blog 表中与 author 关联的字段-->
<!--<association property="author" javaType="Author" column="author_id"
select="com.zhaoxueer.learn.dao.AuthorMapper.selectById">
</association>-->
<!--column 为 blog 表中与 post 关联的字段-->
<collection property="posts" ofType="Post" column="id"
select="com.zhaoxueer.learn.dao.PostMapper.selectByBlogId">
</collection>
</resultMap>
<select id="getBlogById3" resultMap="blogResultMapSelect">
select
b.id,
b.name,
b.remark,
b.author_id
from blog b
where b.id = #{id}
</select>
com.zhaoxueer.learn.dao.PostMapper.selectByBlogId 如下:
<select id="selectByBlogId" resultType="Post" >
select
id, title, content, date
from post
where blog_id = #{id}
</select>
执行结果:
DEBUG [main] - ==> Preparing: select b.id, b.name, b.remark, b.author_id from blog b where b.id = ?
DEBUG [main] - ==> Parameters: 1(Integer)
DEBUG [main] - <== Total: 1
Blog{id=1, name='Sylvia的blog', remark='备注1', status=null}
我要睡觉了zzz...
我睡醒了!一共睡了 5 秒...
DEBUG [main] - ==> Preparing: select id, title, content, date from post where blog_id = ?
DEBUG [main] - ==> Parameters: 1(Integer)
DEBUG [main] - <== Total: 2
Post{id=1, title='MyBatis Learn 01', content='MyBatis Mapper XML-a', date=Thu Mar 28 22:49:11 CST 2019, blogId=0}
Post{id=2, title='MyBatis Learn 02', content='MyBatis Mapper XML-Collection', date=Thu Mar 28 22:57:35 CST 2019, blogId=0}
从执行结果可以看出,在开启懒加载后,我们执行关联查询,会先查出主对象 Blog,然后当程序 sleep 5 秒后我们再获取关联的 posts,它才会去执行关联的查询语句:com.zhaoxueer.learn.dao.PostMapper.selectByBlogId。
附:
当前版本:mybatis-3.5.0
官网文档:MyBatis
项目实践:MyBatis Learn
手写源码:MyBatis 简易实现