MyBatis局部定义的懒加载何时被调用
一.定义局部的懒加载
在主从表查询时,查订单信息要求带出订单详细信息
<select id="getById" resultMap="OrderResultMap"> select * from mall_order where id=#{id} </select> <resultMap id="OrderResultMap" type="Order"> <id column="id" property="id"/> <result column="userid" property="userId"/> <result column="orderno" property="orderNo"/> <result column="orderdate" property="orderDate"/> <!--property,映射到结果的字段和属性,此处映射到订单实体类中的订单详情List--> <!--column,数据库中的列名,或者是列的别名,传递给嵌套 Select 查询语句的列名--> <!--fetchType,有效值为lazy 和 eager,置为lazy时,代表需要property中的值才调用嵌套select--> <!--select,嵌套查询子句--> <collection property="orderDetilsList" column="id" fetchType="lazy" select="com.woniu.mall.dao.OrderDetilsDAO.getByOrderId"/> </resultMap>
在这里使用 fetchType 定义了一个局部的懒加载,当查询订单需要订单详细时就启动懒加载,以执行嵌套的selcet子查询
二.懒加载的子查询何时能启动?
1.通过子查询目标结果的 get/set方法
在订单表中定义了,List<OrderDetils> orderDetilsList; 订单列属性
public class Order { private int id; private int userId; private User user; private String orderNo; //省略若干属性 List<OrderDetils> orderDetilsList; //以下省略若干get set }
测试访问订单详情属性get,启动懒加载
@Test public void testGetById(){ Order order = dao.getById(1); //getOrderDetilsList 此时启动了懒加载会查询订单的详情 System.out.println(order.getOrderDetilsList()); //order.getOrderDetilsList().forEach(c-> System.out.println(c)); }
如下图,两句Sql,查询了订单详情说明触发了懒加载
如果不访问需要信息的get,而是其他的会不会启动懒加载?
@Test public void testGetById(){ Order order = dao.getById(1); //这里没有访问订单详细属性的get,而是Order中其他的属性get System.out.println(order.getOrderNo()); //order.getOrderDetilsList().forEach(c-> System.out.println(c)); }
显然只查询了订单的信息,没有触发懒加载
2.如果调用了"equals", "clone", "hashCode", "toString"方法,也会触发懒加载,至于原因此处不做解释。
注意!Order订单表中即使重写了toString等方法,且在其中没有加入订单详情的信息,在查询时依然会触发懒加载
@Override public String toString() { return "Order{" + "id=" + id + ", userId=" + userId + ", user=" + user + ", orderNo='" + orderNo + '\'' + //这里并没有加入List<OrderDetils> orderDetilsList '}'; }
测试
@Test public void testGetById(){ Order order = dao.getById(1); //System.out.println(order.getOrderNo()); System.out.println(order); }
结果如下图,可以看出红色部分,触发了懒加载,查询了订单详细信息