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 简易实现

上一篇下一篇

猜你喜欢

热点阅读