1.开启二级缓存mybatis-config.xml中配置
<settings>
<!--
开启二级缓存:在mybatis中只要缓存的配置指的都是二级缓存
可以只针对一个mapping进行配置缓存使用cache标签
-->
<setting name="cacheEnabled" value="true"/>
</settings>
2.针对一个mapping配置缓存(当然mybatis配置文件中的总开关是要配的) PersonMapper.xml该映射文件在mapper标签内,开头加入
<!--
当前映射文件开启二级缓存
eviction:逐出缓存的策略
属性: 常用:FIFO(先进先出)
LRU(最近最少使用的,移除最长时间不被使用的对象)
不常用:SOFT(软引用:移除基于垃圾回收器状态和软引用规则的对象)
WEAK(弱引用:更积极的移除基于垃圾回收器状态和软引用规则的对象)
flushInterval:缓存刷新的频率(一毫秒为单位相当于定时器)
size:缓存大小(以个为单位)
readOnly:(true,false)缓存数据是不是可修改
type:引入外部的二级缓存
-->
<cache/>
3.Model类中实现Serializable该接口,如果不实现该接口使用二级缓存将会抛出异常
import java.io.Serializable;
public class Person implements Serializable {
private Integer id;
private String name;
.......
}
/*异常信息*/
org.apache.ibatis.cache.CacheException: Error serializing object. Cause: java.io.NotSerializableException: zhou.model.Person$$EnhancerByCGLIB$$2724db14
3.测试
/**
* mybatis的缓存
* 二级缓存:可以自己配置管理
*/
public class AppTest04 {
SqlSessionFactory sessionFactory;
@Before
public void setUp() throws Exception {
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
sessionFactory = new SqlSessionFactoryBuilder().build(in);
}
/*
* 二级缓存:可以跨SessonFactory范围之内跨Session
* 可以放在内存跟硬盘上,一般会放在硬盘上,需要在Model类中实现Serializable该类
* 实现该类之后便可将二级缓存放入硬盘
* */
@Test
public void selectPersonByIdLazy() {
SqlSession session = sessionFactory.openSession();
try {
/*
*首先:去查询二级缓存如果有数据就从其中拿出数据就可以,如果没有数据去一级缓存中来查,一级缓存中也没有,去数据库查
*然后:查到数据后会在一级缓存及二级缓存中都会放入数据
* */
Person person = session.selectOne("mappings.PersonMapper.selectPersonByIdLazy", 1);
System.out.println(person.toString());
} finally {
session.close();
}
SqlSession session2 = sessionFactory.openSession();
try {
Person person2 = session2.selectOne("mappings.PersonMapper.selectPersonByIdLazy", 1);
System.out.println(person2.toString());
} catch (Exception e) {
e.printStackTrace();
} finally {
session2.close();
}
}
/*
* 二级缓存:可以跨SessonFactory范围之内跨Session
* 可以放在内存跟硬盘上,一般会放在硬盘上,需要在Model类中implements Serializable该类
* 实现该类之后便可将二级缓存放入硬盘
* */
@Test
public void selectPersonByIdLazy1() {
SqlSession session = sessionFactory.openSession();
try {
/*
*首先:去查询二级缓存如果有数据就从其中拿出数据就可以,如果没有数据去一级缓存中来查,一级缓存中也没有,去数据库查
*然后:查到数据后会在一级缓存及二级缓存中都会放入数据
* */
Person person = session.selectOne("mappings.PersonMapper.selectPersonByIdLazy", 1);
System.out.println(person.toString());
} finally {
session.close();
}
SqlSession session3 = sessionFactory.openSession();
try {
/*
*和一级缓存同理,数据库变更会清掉所影响的缓存
* 注意:清不清理缓存是可以配置的,一级缓存也是第4点进行配置
* flushCache默认是true,清空缓存,false不清空缓存
* useCache:默认是true,启用二级缓存,false禁用
* */
Person person3 = new Person();
person3.setGender(1);
person3.setBirthday(new Date());
person3.setAddress("中国");
person3.setName("zhouzhou");
session3.insert("mappings.PersonMapper.insert", person3);
}catch (Exception e){
session3.commit();
session3.rollback();
}
finally {
session3.close();
}
SqlSession session2 = sessionFactory.openSession();
try {
Person person2 = session2.selectOne("mappings.PersonMapper.selectPersonByIdLazy", 1);
System.out.println(person2.toString());
} catch (Exception e) {
e.printStackTrace();
} finally {
session2.close();
}
}
}
4.配置当前查询是否启用二级缓存及清空缓存
这两属性在增删改查都有
<!--
useCache:默认是true,启用二级缓存,false禁用
flushCache默认是true,清空缓存,false不清空缓存
-->
<select id="selectPersonByIdLazy" parameterType="int" resultMap="selectPersonByIdLazyRM" useCache="false" flushCache="false">
select * from Person t where t.id = #{id}
</select>