ssm框架学习---mybatis中延迟加载实现


在处理查询结果中,如果需要延迟加载,即属于对查询结果有要求的那种,需要使用resultMap来实现,并结合association或者collection,

引入延迟加载的目的:单表或者简单联合查询速度较快,通过延迟加载可以按需加载,减轻数据库的压力。

假设需求时查询订单时延迟加载所关联的用户信息,定义mapper.xml文件如下;

    <!--需求:实现延迟加载,先查询出订单信息,然后再延迟加载订单所对应的用户信息-->
<!--定义延迟加载的resultmap,因为只有resultMap有延迟加载的功能,因此这里不能够使用resultType-->
<resultMap id="OrdersCustomerLazyLoadingMap" type="com.ajin.mybatis.model.OrdersCustomerMap">
<!--配置订单的基本信息-->
<id column="ono" property="ono"></id>
<result column="otime" property="otime"></result>
<result column="gno" property="gno"></result>
<result column="cno" property="cno"></result>
<!--配置关联的用户信息,使用association实现延迟加载
select:用来指定延迟加载查询语句的sql,这里引用了CustomerMapper中的statement,因此需要添加完整命名空间
column:用来指定关联的用来关联查询的属性
-->
<association property="customer" javaType="com.ajin.mybatis.model.Customer" select="com.ajin.mybatis.mapper.CustomerMapper.selectCustomerById" column="cno">
<!--需要注意这里和普通的一对一关联查询不一样,这里面不需要写任何东西-->
</association>
</resultMap>
<!--这里面只需要编写单表查询订单的sql语句-->
<select id="selectOrdersCustomerLazyLoading" resultMap="OrdersCustomerLazyLoadingMap">
select * from orders;
</select>
其中在association中引用了一个依据id查询Customer的statement,它的定义如下:

<?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.ajin.mybatis.mapper.CustomerMapper">
<select id="selectCustomerById" parameterType="int" resultType="com.ajin.mybatis.model.Customer">
select * from customer where cno=#{value}
</select>
</mapper>
至于这个statement对应的接口定义这里就不列出来了,很简单。

接下来是上述mapper.xml对应的接口定义如下:

package com.ajin.mybatis.mapper;

import com.ajin.mybatis.model.OrdersCustomerMap;
import com.ajin.mybatis.model.OrdersCustomer;

import java.util.List;

/**
* Created by ajin on 16-12-19.
*/
public interface OrdersCustomerMapper {
//基于resultType方式一对一查询
public OrdersCustomer selectOrdersCustomerById(int id);
//基于resultMap方式一对一查询
public OrdersCustomerMap selectOrdersCustomerMapById(int id);
//延迟加载接口方法定义
public List<OrdersCustomerMap> selectOrdersCustomerLazyLoading();
}
在编写测试用例之前,需要将上述的xml文件添加到sqlMapConfig.xml的mybatis配置文件中,同时因为需要用到延迟加载功能,但是默认没有开启,需要如下设置

  <!--配置延迟加载属性,首先打开延迟加载,然后关闭积极加载-->
<settings>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
最后编写我们的测试用例:

package com.ajin.mybatis.mapper;

import com.ajin.mybatis.model.Customer;
import com.ajin.mybatis.model.OrdersCustomerMap;
import com.ajin.mybatis.model.OrdersCustomer;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;

import java.io.InputStream;
import java.util.List;

import static org.junit.Assert.*;

/**
* Created by ajin on 16-12-19.
*/
public class OrdersCustomerMapperTest {
private SqlSessionFactory sqlSessionFactory;
@Before
public void setUp() throws Exception {
String resource = "config/SqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}


@Test
public void selectOrdersCustomerById() throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
try{
OrdersCustomerMapper ordersCustomerMapper = sqlSession.getMapper(OrdersCustomerMapper.class);
OrdersCustomer ordersCustomer=ordersCustomerMapper.selectOrdersCustomerById(5);
System.out.println(ordersCustomer);
}finally {
sqlSession.close();
}
}

@Test
public void selectOrdersCustomerMapById() throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
try{
OrdersCustomerMapper ordersCustomerMapper = sqlSession.getMapper(OrdersCustomerMapper.class);
OrdersCustomerMap ordersCustomer=ordersCustomerMapper.selectOrdersCustomerMapById(5);
System.out.println(ordersCustomer);
}finally {
sqlSession.close();
}
}

@Test
public void selectOrdersCustomerLazyLoading() throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
try{
OrdersCustomerMapper ordersCustomerMapper = sqlSession.getMapper(OrdersCustomerMapper.class);
//在执行下面这句的时候,只是会执行对于订单表的单表查询
// 日志输出如下:
// DEBUG [main] - ==> Preparing: select * from orders;
// DEBUG [main] - ==> Parameters:
// DEBUG [main] - <== Total: 7
List<OrdersCustomerMap> lists=ordersCustomerMapper.selectOrdersCustomerLazyLoading();
for(OrdersCustomerMap list:lists){
//在执行这一句话时才会延迟加载去获得所关联的用户信息
// 日志输出如下:
// DEBUG [main] - ==> Preparing: select * from customer where cno=?
// DEBUG [main] - ==> Parameters: 1(Integer)
// DEBUG [main] - <== Total: 1
// Customer{cno=1, cname='zcj', csex='male', cphone='13036144569', caddress='wuhan'}
//并且在查询相同的id时,并不会从新生成sql语句,这就涉及到一级缓存了
Customer customer =list.getCustomer();
System.out.println(customer);
}
}finally {
sqlSession.close();
}
}


}
使用collection的方法类似,当然如果框架没有提供,我们可以采用二次调用不同mapper的接口方法来实现延迟加载,框架只是将这一层给封装到了一起,内部原理仍然如此

智能推荐

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
© 2014-2019 ITdaan.com 粤ICP备14056181号  

赞助商广告