Mybatis-延迟加载

什么是延迟加载

延迟加载的条件:resultMap可以实现高级映射(使用association、collection实现一对一及一对多映射),association、collection具备延迟加载功能。
延迟加载的好处:
先从单表查询、需要时再从关联表去关联查询,大大提高 数据库性能,因为查询单表要比关联查询多张表速度要快。
延迟加载的实例:
如果查询订单并且关联查询用户信息。如果先查询订单信息即可满足要求,当我们需要查询用户信息时再查询用户信息。把对用户信息的按需去查询就是延迟加载。

如何开启延迟加载功能

Mybatis的延迟加载功能默认是关闭的
需要在SqlMapConfig.xml文件中通过setting标签配置来开启延迟加载功能
开启延迟加载的属性:
lazyLoadingEnabled:全局性设置懒加载。如果设为‘false’,则所有相关联的都会被初始化加载。默认为false
aggressiveLazyLoading:当设置为‘true’的时候,懒加载的对象可能被任何懒属性全部加载。否则,每个属性都按需加载。默认为true
配置

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

Mapper文件

现在我们要实现一个功能:查询orders表中所有的信息,并根据每一行中的user_id从user表中查询user的信息.

SELECT orders.*,`user`.* from orders,`user` where orders.user_id = `user`.id

但是有时候我们只需要orders的数据,而暂时不需要user的数据,等到有人要查询的时候再加载user的数据.
即先执行

SELECT orders.*  from orders

等需要的时候再执行

SELECT user.*  from user where id = orders.user_id

我们可以使用resultMap中的association来实现
第一个statement

<select id="OrderUserLazyLoadingResult" resultMap="OrderUserLazyLoadingResultMap">
		select * from orders
	</select>

第二个statement

<select id="findUserById" parameterType="int" resultType="mybatis.com.entity.User">
		select * from user where id = #{value}
	</select>

现在整合两个statement来实现延迟加载

<resultMap type="mybatis.com.entity.Orders" id="OrderUserLazyLoadingResultMap">
		<!-- 配置映射的订单信息 -->
		<id column="id" property="id"/>
		<result column="user_id" property="user_id"/>
		<result column="num" property="num"/>
		<result column="createtime" property="createtime"/>
		<result column="note" property="note"/>
		<!-- 配置映射的用户信息 -->
		<!-- 
			实现用户的延迟加载
			select:指定延迟加载需要执行的statement的id(即查询用户的<select></select>)
			column:订单信息中关联用户查询的列,即user_id,要传入findUserById的参数
		 -->
		<association property="user" javaType="mybatis.com.entity.User" select="findUserById" column="user_id">
		</association>
	</resultMap>

测试

@Test
    public void findOrderUser() throws IOException{
	String resource = "SqlMapConfig.xml";
	InputStream inputStream = Resources.getResourceAsStream(resource);
	SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
	SqlSession sqlSession = sqlSessionFactory.openSession();
	OrdersMapperCustom ordersMapperCustom = sqlSession.getMapper(OrdersMapperCustom.class);
	List<Orders> orders = ordersMapperCustom.OrderUserLazyLoadingResult();
	sqlSession.close();
    }

日志如下:
在这里插入图片描述
从日志可以看出只执行了select * from orders 而 没有执行select * from user

总结

不使用mybatis提供的association及collection中的延迟加载功能,如何实现延迟加载??
实现方法如下:
定义两个mapper方法:
1、查询订单列表
2、根据用户id查询用户信息
实现思路:
先去查询第一个mapper方法,获取订单信息列表
在程序中(service),按需去调用第二个mapper方法去查询用户信息。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值