mybatis - 懒加载
mybatis - 懒加载
细肉云吞 发表于1个月前
mybatis - 懒加载
  • 发表于 1个月前
  • 阅读 13
  • 收藏 0
  • 点赞 0
  • 评论 0

腾讯云 十分钟定制你的第一个小程序>>>   

什么是延迟加载

延迟加载即在进行关联查询时,关联的数据不是马上查询出来,而是在需要的时候才进行查询,即关联数据使用时才到数据库查询。在mapper中resultMap可以实现返回结果的高级映射(使用association、collection实现一对一及一对多映射),其中association、collection具备延迟加载功能。

延迟加载相关配置

全局配置文件mybatis-config.xml中有两个配置项:

    <settings>
        <setting name="lazyLoadingEnabled" value="true"/>
        <setting name="aggressiveLazyLoading" value="false"/>
    </settings>
  • lazyLoadingEnabled:延迟加载的总开关,默认值是false
  • aggressiveLazyLoading:默认值是true。启用时,当发生延迟加载懒加载对象时,懒加载对象里面的所有懒加载对象将会进行查询。

除了打开上面你的开关外,还需要加入cglib依赖。

		<dependency>
			<groupId>cglib</groupId>
			<artifactId>cglib</artifactId>
			<version>3.2.5</version>
		</dependency>

一对一查询

需求:查询订单后,延迟加载订单相关的用户信息

** OrderDaoMapper.xml **

与关联查询不同的是,在mapeer中不再使用join关联查询,而是分两步查询这些信息:第一步查询所有的订单;第二步根据订单表里面的user_id查询用户表的数据。需要配置association,告诉它怎么查询延迟对象。具体看下面的注释。

<resultMap type="com.github.thinwonton.mybatis.sample.vo.OrderUserVO" 
        id="OrderUserVOResultMap">
    
        <id column="oid" property="id"/>
        <result column="uid" property="userId"/>
        <result column="create_time" property="createTime"/>
    
        <!-- 
        加载需要懒加载对象User使用的查询语句,这里重用了UserDaoMapper.xml映射文件中的getById语句
        select="com.github.thinwonton.mybatis.sample.advanced.dao.UserDao.getById" 
         -->
        <!--
        column="uid" 把上面结果映射中的uid作为getById语句的输入参数
        -->
        <association property="user" javaType="User" 
            select="com.github.thinwonton.mybatis.sample.advanced.dao.UserDao.getById" 
            column="uid">
        </association>
    </resultMap>
    <select id="listOrderUserVO" resultMap="OrderUserVOResultMap">
        <!-- 
                                    查询所有的order
         -->
		SELECT
		    o.id oid,
		    o.create_time,
		    o.user_id uid
		FROM
		    `order` o
    </select>

UserDaoMapper.xml

<mapper namespace="com.github.thinwonton.mybatis.sample.advanced.dao.UserDao">

	<!-- 数据库名 -->
	<sql id="TBL_USER">`user`</sql>

	<!-- 数据库的列 -->
	<sql id="base_column_list">
		id, user_name, sex, addr
	</sql>

	<!-- User对象的映射关系 -->
	<resultMap id="beanMap" type="User">
		<result column="id" property="id" />
		<result column="user_name" property="userName" />
		<result column="sex" property="sex" />
		<result column="addr" property="addr" />
	</resultMap>

	<select id="getById" parameterType="long" resultMap="beanMap"
		useCache="true">
		select
		<include refid="base_column_list" />
		from
		<include refid="TBL_USER" />
		<where>
			id = #{id}
		</where>
	</select>
</mapper>

测试程序 

	/**
	 * 查询订单以及它相关用户信息
	 */
	@Test
	public void test_lazyLoad_listOrderUserVO() {
		SqlSession sqlSession = sqlSessionFactory.openSession();
		OrderDao orderDao = sqlSession.getMapper(OrderDao.class);

		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.SSS");
		List<OrderUserVO> list = orderDao.listOrderUserVO();  //观察点1
		for (OrderUserVO orderUserVO : list) {
			System.out.println("oid: " + orderUserVO.getId());
			System.out.println("uid: " + orderUserVO.getUserId());
			System.out.println("order create time: " + dateFormat.format(orderUserVO.getCreateTime()));
			System.out.println("uid: " + orderUserVO.getUser().getId());  //观察点2
			System.out.println("user name: " + orderUserVO.getUser().getUserName()); 
			System.out.println("user sex: " + orderUserVO.getUser().getSex());
			System.out.println("user addr: " + orderUserVO.getUser().getAddr());
			System.out.println("----------------------");
		}
	}

DEBUG调试后,当程序运行到观察点1时,将查询数据库获取所有的订单信息;当程序运行到达观察点2,将会到数据库查询User对象。

一对多查询

需求:查询所有的用户,延迟查询用户的订单。

UserDaoMapper.xml

 <resultMap id="UserOrderResultMap"
         type="com.github.thinwonton.mybatis.sample.vo.UserOrderVO" >
         
         <id column="uid" property="id"/>
         <result column="user_name" property="userName"/>
         <result column="sex" property="sex"/>
         <result column="addr" property="addr"/>
         
         <collection property="orders" ofType="Order" 
            select="com.github.thinwonton.mybatis.sample.advanced.dao.OrderDao.getByUserId"
            column="uid"
         >
            <id column="oid" property="id"/>
            <result column="uid" property="userId"/>
            <result column="create_time" property="createTime"/>
         </collection>
    </resultMap>
    <select id="listUserOrder" resultMap="UserOrderResultMap">
        SELECT
            u.id uid,
            u.user_name,
            u.sex,
            u.addr
        FROM
            `user` u
    </select>

OrderDaoMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.github.thinwonton.mybatis.sample.advanced.dao.OrderDao">

	<!-- 数据库表名 -->
	<sql id="TBL_ORDER">`order`</sql>
	
	<!-- 数据库的列 -->
    <sql id="base_column_list">
        id, user_id, create_time
    </sql>

    <!-- User对象的映射关系 -->
    <resultMap id="beanMap" type="Order">
        <result column="id" property="id" />
        <result column="user_id" property="userId" />
        <result column="create_time" property="createTime" />
    </resultMap>

    <select id="getByUserId" parameterType="long" resultMap="beanMap">
        select
        <include refid="base_column_list" />
        from
        <include refid="TBL_ORDER" />
        <where>
            user_id = #{uid}
        </where>
    </select>
</mapper>

测试程序

	@Test
	public void test_lazyLoad_listUserOrder() {
		SqlSession sqlSession = sqlSessionFactory.openSession();
		UserDao userDao = sqlSession.getMapper(UserDao.class);

		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.SSS");
		List<UserOrderVO> list = userDao.listUserOrder();
		for (UserOrderVO userOrderVO : list) {
			System.out.println("uid: " + userOrderVO.getId());
			System.out.println("user name: " + userOrderVO.getUserName());
			System.out.println("user sex: " + userOrderVO.getSex());
			System.out.println("user addr: " + userOrderVO.getAddr());
			List<Order> orders = userOrderVO.getOrders();
			for (Order order : orders) {
				System.out.println("oid: " + order.getId());
				System.out.println("order create time: " + (order.getCreateTime() != null
						? dateFormat.format(order.getCreateTime()) : null));
				System.out.println("uid: " + order.getUserId());
			}
			System.out.println("----------------------");
		}
	}
标签: MyBatis 懒加载
共有 人打赏支持
粉丝 77
博文 101
码字总数 107952
×
细肉云吞
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: