侧边栏壁纸
博主头像
Curllen博主等级

早上的云霞好美~

  • 累计撰写 12 篇文章
  • 累计创建 18 个标签
  • 累计收到 2 条评论

目 录CONTENT

文章目录

mybatis系列(五) mybatis延迟加载

Curllen
2018-11-07 / 0 评论 / 0 点赞 / 833 阅读 / 0 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2020-05-06,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

联级查询时, 很多情况下只需要单张表的数据, 无需查询所有表, 延时加载实现了这个需求, 减少资源的浪费.

使用说明

MyBatis的延迟加载

  • 只能对关联对象进行查询时,使用延迟加载策略。对于主加载对象,均采用直接加载。关联对象以属性的方式添加在主对象中

例如:查询订单表中某个订单信息以及和该订单相关的用户信息:

graph LR
主加载对象:订单对象-->可按需查询的关联对象:用户对象
  • 要应用延迟加载查询,只能使用多表单独查询,而不能使用多表连接查询。因为多表连接查询的本质是查询一张表,将多张表首先连接为了一张表后,再进行的查询。查询一个信息,就会将所有信息全部查询到。

根据前文例子构造用于==非延时加载的传统联合查询的SQL语句==如下:

select * from order o left join user u on  o.user_id=u.id where o.order_number=201810313239

本语句使用了多表连接查询>左连接查询, 延时加载相关设置对其是无效的, 本语句查询结果是一张组合的表, 不可拆解.

改造上文SQL语句,成为适用延时加载SQL语句:

  1. mybatis-config.xml开启全局配置
  2. 添加cglib的依赖(从3.4.1版本开始不用添加)
  3. 添加resultMap和改造原映射文件中SQL语句

相关的pojo:

public class Order implements Serializable {
  private static final long serialVersionUID = 1540810318910L;
  //订单id
  private Integer id;
  //用户id
  private Long userId;
  //订单号
  private String orderNumber;
  //用户
  private User user;
  ...set/get等省略...
public class User {
    private Long id;
    // 用户名
    private String userName;
    // 密码
    private String password;
    // 姓名
    private String name;
    // 年龄
    private Integer age;
    // 性别,1男性,2女性
    private Integer sex;
    // 出生日期
    private Date birthday;
    // 创建时间
    private Date created;
    // 更新时间
    private Date updated;
    ...set/get等省略...

mybatis-config.xml配置

<!-- 全局配置参数 -->
	<settings>
		<!-- 延迟加载总开关 -->
		<setting name="lazyLoadingEnabled" value="true" />	
		<!-- 设置按需加载 -->
		<!-- mybatis在3.4.1开始默认为false-->
		<setting name="aggressiveLazyLoading" value="false" />
	</settings>

pom.xml添加依赖(假定是maven过程)

<!-- https://mvnrepository.com/artifact/cglib/cglib -->
<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>2.2.2</version>
</dependency>

修改映射文件(本例不把resultMap抽取为额外映射文件)

    <resultMap id="orderUserLazyMap" type="Order" autoMapping="true">
        <--
            column:查询结果的id字段
            property:order对象的id属性
            数据库表的主键id映射id, 即使相同也不要省,提高性能
        -->
        <id column="id" property="id" />
        <!--
            property:order对象的user属性
            javaType:属性名对应的java类型
            autoMapping:不写
            select:指定延迟加载要执行的statement的id(是根据user_id查询用户信息
			      的statement,注意:需要前边加namespace
            column:订单表中关联用户表的列,是user_id,作为参数传入statement中,
					只有一个参数时statement中的#{}原则上可以随意.
					如果是多个参数,则需要使用数组,形如:column="{a=user_id,aa=参数2,cc=参数3}",
					使用时在statement中的需要哪个参数,如第二个,通过#{aa}/${aa}来使用    
        -->
        <association property="user" javaType="User" select="selectUserById"  column="user_id"/>
    </resultMap>
    <!-- 语句1,查询订单信息 -->
    <select id="selectOrderUserLazy" resultMap="orderUserLazyMap">
      select  *  from tb_order where order_number = #{orderNumber}
    </select>


    <!-- 语句2,查询用户信息 -->
    <select id="selectUserById" resultType="User">
        select * from tb_user where id  = #{id};
    </select>
0

评论区