zoukankan      html  css  js  c++  java
  • 【Mybatis进阶】延迟加载

    首先我们先思考一个问题,假设:在一对多中,我们有一个用户,他有100个订单。

      问题1:在查询用户的时候,要不要把关联的订单查出来?
    问题2:在查询订单的时候,要不要把关联的用户查出来?

      解答:
    在查询用户的时候,用户下的订单信息应该是我们什么时候使用,什么时候去查询。
    在查询订单的时候,订单的所属用户信息应该是随着订单查询时一起查询出来。

      搞清楚这两个简单的问题后,我们就可以引出延迟加载和立即加载的特性。

      延迟加载:在真正使用数据的时候才发起查询,不用的时候不查询关联的数据,延迟加载又叫按需查询(懒加载)
    立即加载:不管用不用,只要一调用方法,马上发起查询。

    还有一个实际的应用场景,就是一篇文章和文章中的图片,文章是立即加载,而文章关联的图片是在用到的时候才加载。相信大家都有过这种体检,就是用手机阅读文章的时候,只有阅读到有图片的位置,图片就会转圈圈加载,这也是延迟加载(懒加载)的体现,相信大家应该能明白其中的奥秘了。

    实例

      理解了延迟加载的特性以后再看Mybatis中如何实现查询方法的延迟加载,在MyBatis的配置文件中通过设置settings的lazyLoadingEnabled属性为true进行开启全局的延迟加载,通过aggressiveLazyLoading属性开启立即加载。

    还是老例子,用户和订单。本篇博客基于mybatis的环境已经搭建完成,如果不知道如何搭建,具体可以阅读笔者的博客——【从零开始学Mybatis笔记(三)】Dao开发方法

    第一步:先把查询用户和订单的SQL写出来

        <!-- 通用查询结果列-->
        <select id="findAll" resultMap="userOrder">
            SELECT *
            FROM user
        </select>
    
        <select id="findOrderbyUserId" parameterType="int" resultType="Orders">
            select * from `orders` where user_id = #{userId}
        </select>
    

    第二步:resultMap
    第一步中我们使用的resultMap是延迟加载的关键,如下:

        <resultMap id="userOrder" type="com.tyust.entity.User">
            <id property="id" column="id"></id>
            <result property="username" column="username"></result>
            <result property="birthday" column="birthday"></result>
            <result property="sex" column="sex"></result>
            <result property="address" column="address"></result>
            <!--        property对应User的属性orders
                        ofType对应orders中每一个元素对应的属性,因为orders是一个Order类的集合,所以就是Order类
                        javaType对应的就是order的java类型,就是List
                        select就是关联的查询方法
                        column就是user的属性,也是select中方法的参数,注意不是user_id-->
            <collection property="orders" ofType="com.tyust.entity.Orders"
                        select="com.tyust.dao.OrderMapper.findOrderbyUserId" column="id"/>
        </resultMap>
    

    第三步:打开延迟加载设置

        <settings>
            <!-- 打开延迟加载的开关 -->
            <setting name="lazyLoadingEnabled" value="ture"/>
            <!-- 将积极加载改为消极加载,即延迟加载 -->
            <setting name="aggressiveLazyLoading" value="false"/>
        </settings>
    

    第四步:调试

    当我们不使用User类的orders属性时,运行程序。

    这时候我们把循环打印order的代码取消注释,再次运行程序。

    结果就多出来好几条子查询。

    如果我们把lazyLoadingEnabled的值改成false。就不会有这样的效果。

    参考文献

    Mybatis延迟加载的实现以及使用场景
    【MyBatis学习11】MyBatis中的延迟加载

  • 相关阅读:
    linux如何查看ip地址
    mybais-plus整合springboot自动代码生成。
    org.springframework.beans.factory.UnsatisfiedDependencyException 问题
    springboot中使用AOP做访问请求日志
    springboot集成swagger
    springboot中的跨域问题
    spring中的ApplicationListener
    spring中的BeanDefinitionRegistryPostProcessor
    spring中的BeanFactoryPostProcessor
    servlet中ServletContainerInitializer
  • 原文地址:https://www.cnblogs.com/zllk/p/14245169.html
Copyright © 2011-2022 走看看