在MyBatis中使用resultMap可以实现延迟加载,在collection和association标签可以配置延迟加载功能。
1,开启延迟加载配置
<settings>
<!-- 打开延迟加载的开关 -->
<setting name="lazyLoadingEnabled" value="true" />
<!-- 将积极加载改为小计加载即按需加载-->
<setting name="aggressiveLazyLoading" value="false" />
</settings>
2,示例association配置
<!-- 查询订单关联用户,用户信息需要延迟加载 -->
<resultMap type="cn.itcast.mybatis.po.Orders" id="OrdersUserLazyLoading">
<!-- 对用户信息进行延迟加载 -->
<!-- 对订单信息进行映射配置 -->
<id column="id" property="id" />
<result column="user_id" property="userId" />
<result column="number" property="number" />
<result column="createtime" property="createtime" />
<result column="note" property="note" />
<!--
select:指定延时加载需要执行的statement的id(根据user_id查询用户信息)
要事勇UserMapper.xml中的findUserById来完成用户信息的查询
column:订单的信息中关联用户信息查询的列,是user_id
SELECT
orders.*, (
SELECT
username
FROM
USER
WHERE
`user`.id = orders.user_id
) username, (
SELECT
sex
FROM
USER
WHERE
`user`.id = orders.user_id
)sex
FROM
orders
-->
<association property="user" javaType="cn.itcast.mybatis.po.User" select="cn.itcast.mybatis.mapper.UserMapper.findUserById" column="user_id">
</association>
</resultMap>
使用select配置延迟加载时候执行的sql语句。
findUserById:
<select id="findUserById" parameterType="int"
resultType="cn.itcast.mybatis.po.User">
SELECT * FROM user where id=#{value}
</select>
查询配置:
<select id="findOrdersUserLazyLoading" resultMap="OrdersUserLazyLoading">
select * from orders
</select>
测试方法:
@Test
public void findOrdersUserLazyLoading() throws Exception {
SqlSession sqlSession=sqlSessionFactory.openSession();
//创建代理对象
OrdersMapper ordersMapper=sqlSession.getMapper(OrdersMapper.class);
//调用mapper的方法
List<Orders> ordersList=ordersMapper.findOrdersUserLazyLoading();
System.out.println(ordersList.size());
for(Orders orders: ordersList ){
User user=orders.getUser();
System.out.println(user.getUsername());
}
}
debug:
发出的查询语句如上,首先是从orders表中查询orders,之后读取用户信息,再去查询user表,这里查询的时候,因为自带一级缓存的效果,所以id=1的user只被查询了一次。