在Mybatis核心配置文件添加配置开启延迟开关和按需加载(Mybatis 3.4.1 版本后按需加载默认开启)
<settings>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
settings>
以查询账户同时查询该账户所属用户信息为例
映射配置IAccountDao.xml文件中的resultMap
<resultMap id="accountUserMap" type="account">
<id property="id" column="id">id>
<result property="uid" column="uid">result>
<result property="money" column="money">result>
<association property="user" column="uid" javaType="User" select="com.itheima.dao.IUserDao.findById">association>
resultMap>
select属性是IUserDao.xml中的findById方法
当执行测试方法时:
把输出语句注释后:
示例:查询所有用户并查询该用户下的所有账户信息
IUserDao.xml中:
<resultMap id="userAccount" type="User">
<id property="id" column="id">id>
<result property="username" column="username">result>
<result property="birthday" column="birthday">result>
<result property="sex" column="sex">result>
<result property="address" column="address">result>
<collection property="accounts" ofType="Account" select="com.itheima.dao.IAccountDao.findAccountByUid" column="id" >collection>
resultMap>
<select id="findAll" resultMap="userAccount">
select * from user
select>
IAccountDao.xml中:
<select id="findAccountByUid" parameterType="int" resultType="Account">
select * from account where uid = #{uid}
select>
演示:
这里的User对象并没有重写 toString() 方法
/**
* 测试一级缓存
*/
@Test
public void testFirstLevelCache(){
User user1 = userDao.findById(41);
System.out.println(user1);
User user2 = userDao.findById(41);
System.out.println(user2);
System.out.println(user1 == user2);
}
/**
* 测试一级缓存
*/
@Test
public void testFirstLevelCache() throws Exception {
User user1 = userDao.findById(41);
System.out.println(user1);
// 关闭sqlSession对象
sqlSession.close();
// 重新执行初始化方法(重新获取sqlSession对象并生成接口IUserDao的代理对象userDao)
init();
User user2 = userDao.findById(41);
System.out.println(user2);
System.out.println(user1 == user2);
}
除了重新关闭SqlSession对象,还有一个方法可以清空SqlSession对象里的缓存
sqlSession.clearCache();
<update id="updateUser" parameterType="User">
update user set username=#{username}, birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}
update>
测试方法:
/**
* 测试缓存的同步
*/
@Test
public void testCleanCache() {
// 1.根据id查询用户
User user1 = userDao.findById(41);
System.out.println(user1);
// 2.更新用户信息
user1.setUsername("星瞳");
user1.setAddress("星神界");
userDao.updateUser(user1);
// 3.再次根据id查询用户
User user2 = userDao.findById(41);
System.out.println(user2);
System.out.println(user1 == user2);
}
新建测试类:
package com.itheima.test;
import com.itheima.dao.IUserDao;
import com.itheima.domain.User;
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.After;
import org.junit.Before;
import org.junit.Test;
import java.io.InputStream;
/**
* 测试类
*/
public class SecondLevelCacheTest {
private InputStream in;
private SqlSessionFactory factory;
@Before //用于在测试方法执行之前执行
public void init()throws Exception{
//1.读取配置文件,生成字节输入流
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.获取SqlSessionFactory
factory = new SqlSessionFactoryBuilder().build(in);
}
@After//用于在测试方法执行之后执行
public void destroy()throws Exception{
in.close();
}
/**
* 测试二级缓存
*/
@Test
public void testFirstLevelCache() throws Exception {
SqlSession sqlSession1 = factory.openSession();
IUserDao dao1 = sqlSession1.getMapper(IUserDao.class);
User user1 = dao1.findById(41);
System.out.println(user1);
sqlSession1.close(); // 一次缓存清空
System.out.println("---------------------------");
SqlSession sqlSession2 = factory.openSession();
IUserDao dao2 = sqlSession2.getMapper(IUserDao.class);
User user2 = dao2.findById(41);
System.out.println(user2);
sqlSession2.close();
System.out.println(user1==user2);
}
}
当我们未使用二级缓存时执行testFirstLevelCache()测试:
接下来介绍并使用二级缓存
第一步:在Mybatis核心配置文件中添加
不配也行,因为默认值就是true
<settings>
<setting name="cacheEnabled" value="true"/>
settings>
第二步:映射配置文件IUserDao.xml中添加:
<cache/>
第三部:映射配置文件IUserDao.xml中让想支持二级缓存的操作的的select标签中添加属性
当我们使用了二级缓存之后,再次执行testFirstLevelCache()测试: