概述
Mybatis中的延迟加载,也叫做懒加载,是指在关联查询时,按照设置的延迟规则推迟对关联对象的select查询,延迟加载可以有效减少数据库的压力。
嵌套结果与嵌套查询
嵌套结果
在进行一对多的查询时一种类型的sql配置文件如下:
<resultMap id="userListMap" type="user">
<!--id标签,映射查询结果集的唯一列
column: 查询的sql结果中的列名
property:映射结果的属性名
-->
<id column="id_" property="id"/>
<!--result标签:映射结果集的普通列-->
<result column="username_" property="username"/>
<result column="birthday_" property="birthday"/>
<collection property="lstOrders" ofType="Orders">
<id column="id" property="id"/>
<result column="uid" property="uid"/>
<result column="order_name" property="orderName"/>
</collection>
</resultMap>
如上面的案例所示,在resultMap标签里面有collection标签,并且collection标签里面还有映射的内容,这种形式叫做嵌套结果。
嵌套查询
除了嵌套结果之外对应的还有嵌套查询,而嵌套查询与嵌套结果很类似,也是在一对多的查询时候用到,即resultMap标签里面也有collection标签,但是collection标签中没有结果集的一一映射,这种方式用在延迟加载中。
延迟加载的分类
直接加载
执行完对主加载对象的select语句,马上执行对关联对象的select查询。
在mybatis的主配置文件中配置
<!--配置直接延迟加载,默认是false,开启是true-->
<setting name="lazyLoadingEnabled" value="false"/>
- 默认是false,也就是说如果使用默认值(也就是false),所有关联的sql都会查询出来。
一对一的直接加载
比如从订单的角度来看,订单和用户是一对一的关系,一对一可以通过association标签来体现,下面是一对一的直接加载案例。
OrdersMapper.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">
<!--namespace作用是为了分类管理映射文件中的MapperdStatement对象-->
<mapper namespace="top.mapper.OrdersMapper">
<resultMap id="ordersMap" type="Orders">
<id column="id" property="id"></id>
<result column="uid" property="uid" />
<result column="order_name" property="orderName"/>
<association property="user" javaType="user" select="top.mapper.UserMapper.findUserById"
column="uid">
</association>
</resultMap>
<select id="findOrdersById" resultMap="ordersMap" parameterType="int" resultType="Orders" fetchType="lazy">
select * from orders where id = #{id}
</select>
</mapper>
- association标签中的就是嵌套查询,因为该标签里面没有映射关系
- association标签中的property属性表示的是order这个po中的user对象属性
- association中的javaType属性表示的是返回值类型(这里使用user而不是全限定名是因为取了别名)
- select标签是关联用户的查询语句,这里是加载的另外一个mapper文件(UserMapper.xml文件)
- column属性表示是将哪一个参数值代入查询user的那个sql中,因为查询用户的sql中也是需要一个int类型作为参数,而column这个属性就是指定将orders中的uid这个属性值作为用户的查询条件。
- fetchType属性需要设置为lazy,也就是延迟加载。
用户的查询语句UserMapper.xml中
<select id="findUserById" parameterType="int" resultType="user">
select * from user where id = #{id}
</select>
在执行ordersMapper.findOrdersById(int i)
;这个方法的时候不不仅仅会将orders表内容查询出来,还会将user表的内容也会查询出来,这种形式就是直接加载。
侵入式加载
执行对主加载对象的查询时,不会执行对关联对象的查询。但当要访问主加载对象的详情时,就会马上执行关联对象的select查询。即对关联对象的查询执行,侵入到了主加载对象的详情访问中。也可以这样理解:将关联对象的详情侵入到了主加载对象的详情中,即将关联对象的详情作为主加载对象的详情的一部分出现了。
在mybais主配置文件中配置
<!--配置直接延迟加载,默认是false-->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 侵入式延迟加载开关,默认是true -->
<setting name="aggressiveLazyLoading" value="true"/>
- 延迟加载开关需要开启,也就是lazyLoadingEnabled需要设置为true
- 侵入式延迟加载开关需要开启,也就是aggressiveLazyLoading需要设置为true
其余的sql配置文件相同,再来看一下测试代码:
@Test
public void findOrdersById () {
SqlSession sqlSession = sqlSessionFactory.openSession();
OrdersMapper ordersMapper = sqlSession.getMapper(OrdersMapper.class);
Orders orders = ordersMapper.findOrdersById(1);
//System.out.println(orders);
sqlSession.close();
}
如果将System.out.println(orders);这一句代码注释掉,那么只会查询orders这个表,因为没有使用到orders实体,但是如果将这句注释代码打开那么一开始就会既查询orders表也会查询user表,这就是侵入式的特点,因为使用到了orders表。
深度加载
执行对主加载对象的查询时,不会执行对关联对象的查询。访问主加载对象的详情时也不会执行关联对象的select查询。只有当真正访问关联对象的详情时,才会执行对关联对象的select查询
mybatis中的主配置文件
<!--配置直接延迟加载,默认是false-->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 侵入式延迟加载开关,默认是true -->
<setting name="aggressiveLazyLoading" value="false"/>
- 将延迟加载开关设置为true(默认是false,也就是直接加载)
- 将侵入式延迟加载设置为false(默认为true,也就是侵入式延迟加载),就会变成深度延迟加载。
转载于:https://my.oschina.net/guowei11/blog/3086465
最后
以上就是安静电话为你收集整理的嵌套结果、嵌套查询与延迟加载嵌套结果与嵌套查询延迟加载的分类的全部内容,希望文章能够帮你解决嵌套结果、嵌套查询与延迟加载嵌套结果与嵌套查询延迟加载的分类所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复