mybatis的延迟加载
也是指Lazy加载,指的是进行关联查询的时候,按照设定的延迟规则推迟对关联对象的select查询;在真正使用数据的时候才加载数据(发出sql语句查询数据)不用的时候不加载数据(不会发出sql语句)
【***按需加载(懒加载)***】
lazyLoadingEnabled:是否启用延迟加载,mybatis默认为false,不启用延迟加载。lazyLoadingEnabled属性控制全局是否使用延迟加载,特殊关联关系也可以通过嵌套查询中fetchType属性单独配置(fetchType属性值lazy或者eager)。
aggressiveLazyLoading:是否按需加载属性,默认值false,lazyLoadingEnabled属性启用时只要加载对象,就会加载该对象的所有属性;关闭该属性则会按需加载,即使用到某关联属性时,实时执行嵌套查询加载该属性
在对应的四种表关系中:一对多,多对一,一对一,多对多
一对多,多对多:通常情况下我们都是采用延迟加载。
多对一,一对一:通常情况下我们都是采用立即加载
准备工作
1.先搭建好Mybatis的运行环境
这是mybatis的基本运行环境
首先测试运行获取用户下所有的信息包括账户的信息
发现并没有延迟而是立即加载 【立即加载】
我们需求按照需求然后把数据给查询出来
首先需求在Mybatis的全局配置文件开启延迟加载
<settings>
<!--开启Mybatis支持延迟加载-->
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"></setting>
</settings>
这里是我们的接口文件
public interface IUserDao {
/**
* 查询所有用户,同时获取到用户下所有账户的信息
* @return
*/
List<User> findAll();
/**
* 根据id查询用户信息
* @param userId
* @return
*/
User findById(Integer userId);
}
这里是另外一个:
public interface IAccountDao {
/**
* 查询所有账户,同时还要获取到当前账户的所属用户信息
* @return
*/
List<Account> findAll();
/**
* 根据用户id查询账户信息
* @param uid
* @return
*/
List<Account> findAccountByUid(Integer uid);
}
下面是接口的配置映射文件:IUserDaox.ml
<?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="www.henan.dao.IUserDao">
<resultMap id="userAccountMap" type="www.henan.domain.User">
<id column="id" property="id"></id>
<result column="username" property="username"></result>
<result column="address" property="address"></result>
<result column="sex" property="sex"></result>
<result column="birthday" property="birthday"></result>
//开启延迟加载 这里需要我们select
//这里的select 对应的实IAccountDao里面的根据Id查询用户的接口方法
<collection property="accounts" ofType="www.henan.domain.Account" select="www.henan.dao.IAccountDao.findAccountByUid" column="id" fetchType="lazy" ></collection>
</resultMap>
<!--查询所有用户,同时获取到用户下所有账户的信息
List<User> findAll();-->
<select id="findAll" resultMap="userAccountMap">
select * from user
</select>
<!-- /**
* 根据id查询用户信息
* @param userId
* @return
*/
User findById(Integer userId);-->
<select id="findById" parameterType="int" resultType="www.henan.domain.User">
select * from user where id =#{uid}
</select>
</mapper>
这里是另外一个配置映射文件:IAccountDao.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="www.henan.dao.IAccountDao">
<resultMap id="AccountUserMapper" type="www.henan.domain.Account">
<id column="ID" property="id"></id>
<result column="UID" property="uid"></result>
<result column="MONEY" property="money"></result>
<!-- 一对一的关系映射:配置封装user的内容
select属性指定的内容:查询用户的唯一标识:
column属性指定的内容:用户根据id查询时,所需要的参数的值
-->
<!--延迟加载-->
<association property="user" column="uid" select="www.henan.dao.IUserDao.findById" fetchType="lazy"></association>
</resultMap>
<!--查询所有-->
<select id="findAll" resultMap="AccountUserMapper">
select * from account
</select>
<!-- /**
* 根据用户id查询账户信息
* @param uid
* @return
*/
List<Account> findAccountByUid(Integer uid);-->
<select id="findAccountByUid" parameterType="int" resultType="www.henan.domain.Account">
select * from account where UID=#{uId}
</select>
</mapper>
这里我们可以测试实现的延迟加载:
public class TestUser {
private InputStream in;
private SqlSession sqlSession;
private IUserDao userDao;
@Before//用于在测试方法执行之前执行
public void init() throws Exception {
//1.读取配置文件,生成字节输入流
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.获取SqlSessionFactory
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
//3.获取SqlSession对象
sqlSession = factory.openSession(true);
//4.获取dao的代理对象
userDao = sqlSession.getMapper(IUserDao.class);
}
@After//用于在测试方法执行之后执行
public void destroy() throws Exception {
//提交事务
sqlSession.commit();
//6.释放资源
sqlSession.close();
in.close();
}
/**
* 查询所有用户,同时获取到用户下所有账户的信息
*/
@Test
public void testFindAll() {
List<User> list = userDao.findAll();
for (User user:list){
System.out.println("--------");
System.out.println(user);
System.out.println(user.getAccounts());
}
}
/**
* 根据id查询用户
*/
@Test
public void testFindById(){
User user = userDao.findById(41);
System.out.println(user);
}
}
这里是控制套输出的信息:
通过配置mybatis的全局配置文件
再修改mapper的映射文件实现了mybatis的延迟加载
再次总结
这里我们需要在mybatis全局配置文件中开启延迟加载
<settings>
<!--开启Mybatis支持延迟加载-->
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"></setting>
</settings>
然后根据延迟加载的关键字:
fetchType="lazy"
这里是mybatis的抓去策略
默认有三种情况
lazy :延迟加载
eager:立即加载
default:默认加载