在hibernate中只需要在配置文件中进行简单的配置即可实现延迟加载功能, 在MyBatis中需要手写sql语句来实现
首先需要在"sqlMapConfig.xml"配置文件中进行如下配置:
<!-- 配置延迟加载
lazyLoadingEnabled: 延迟加载的总开关
aggressiveLazyLoading: 配置延迟加载是否启用 true: 不启用(积极地加载, 则非延迟加载)
-->
<settings>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
延迟加载有主sql和子sql的概念
1 一对多延迟加载
"PersonMapper.xml"配置文件:
<resultMap type="person" id="selectPersonByIdLazyRM" extends="BaseResultMap">
<!--
column: 传递person_id的值给子sql
select: 指定具体的子sql
-->
<collection property="orderList" column="person_id" select="com.rl.mapper.OrdersMapper.selectOrdersByPersonIdLazy"></collection>
</resultMap>
<select id="selectPersonByIdLazy" parameterType="int" resultMap="selectPersonByIdLazyRM">
select * from person p where p.person_id = #{personId}
</select>
一般把子sql写在相应的mapper中
"OrdersMapper.xml"配置文件:
<select id="selectOrdersByPersonIdLazy" parameterType="int" resultMap="BaseResultMap">
select * from orders o where o.person_id = #{personId}
</select>
测试代码:
@Test
public void test() {
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
//发出主sql
Person person = sqlSession.selectOne("com.rl.mapper.PersonMapper.selectPersonByIdLazy", 1);
//发出子sql
System.out.println(person.getOrderList());
} finally{
sqlSession.close();
}
}
2 多对一延迟加载
"OrdersMapper.xml"配置文件:
主sql:
<resultMap type="orders" id="selectOrdersByIdLazyRM" extends="BaseResultMap">
<association property="person" column="person_id" select="com.rl.mapper.PersonMapper.selectPersonById"></association>
</resultMap>
<select id="selectOrdersByIdLazy" parameterType="int" resultMap="selectOrdersByIdLazyRM">
select * from orders o where o.order_id = #{orderId}
</select>
子sql在PersonMapper.xml中是之前的已经写好的, 直接使用即可, 就不贴出来了
测试代码:
@Test
public void test1() {
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
//发出主sql
Orders order = sqlSession.selectOne("com.rl.mapper.OrdersMapper.selectOrdersByIdLazy", 1);
//发出子sql
System.out.println(order.getPerson());
} finally{
sqlSession.close();
}
}
3 联合一对多跟多对一使用延迟加载
场景: 利用订单表查询人员表跟明细表
"OrdersMapper.xml"配置文件:
<!-- 多对一和一对多联合的主sql -->
<resultMap type="orders" id="selectOrdersByOrderIdLazyRM" extends="selectOrdersByIdLazyRM">
<!--
通过继承"selectOrdersByIdLazyRM"的方式, 精简了多对一的"association"
-->
<collection property="detailList" column="order_id" select="com.rl.mapper.OrderDetailMapper.selectDetailByOrderIdLazy"></collection>
</resultMap>
<select id="selectPersonAndDetailByOrderIdLazy" parameterType="int" resultMap="selectOrdersByOrderIdLazyRM">
select * from orders o where o.order_id = #{orderId}
</select>
"OrderDetailMapper.xml"配置文件:
<!-- 多对一和一对多联合的子sql -->
<select id="selectDetailByOrderIdLazy" parameterType="int" resultMap="BaseResultMap">
select * from order_detail od where od.order_id = #{orderId}
</select>
测试代码:
@Test
public void test2() {
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
//发出主sql
Orders order = sqlSession.selectOne("com.rl.mapper.OrdersMapper.selectPersonAndDetailByOrderIdLazy", 1);
//发出子sql
System.out.println(order.getPerson());
//发出子sql
System.out.println(order.getDetailList());
} finally{
sqlSession.close();
}
}