根据作用域和生命周期分为两种:
一级缓存: 同一线程(SqlSession)间共享缓存,sqlSession一旦关闭,缓存将不复存在。
一级缓存只要用就有,一直处于开启状态。
二级缓存: 不同线程间共享缓存(不同SqlSession 同一个namespace ),与整个应用生命周期是一致的
按照namespace划分,不同的互不干扰
证明一级缓存是存在的
Student student = dao.selectStudentById(2);
System.out.println(student);
Student student2 = dao.selectStudentById(2);
System.out.println(student2);
运行结果:只进行了一次查询,证明一级缓存是存在的
Mybatis:证明一级缓存中读取数据的依据是SQL id + SQL语句
Hibernate:缓存中读取数据的依据是查询结果对象id
ORM架构不同,查询依据不同
public interface IStudentDao {
Student selectStudentById(int id);
Student selectStudentById2(int id);
}
public void test02(){
Student student = dao.selectStudentById(2);
System.out.println(student);
Student student2 = dao.selectStudentById(2);
System.out.println(student2);
}
查询依据肯定不是对象id
查询依据其实是SQL id和sql语句,缓存底层结构是个map,value是对象id(查询结果),key是SQL id和其对应的sql语句。
增删改操作会刷新一级缓存(清空一级缓存)
无论是否提交
public void test03(){
Student student = dao.selectStudentById(2);
System.out.println(student);
dao.insertStudent(new Student("赵六",25,93));
Student student2 = dao.selectStudentById(2);
System.out.println(student2);
}
使用二级缓存的目的不是在多个查询中共享查询结果。而是为了防止同一查询(同SQL id 同SQL语句)的反复执行。
证明二级缓存是存在的
//证明二级缓存是存在的
@Test
public void test01(){
sqlSession = MyBatisUnils.getSqlSession();
dao = sqlSession.getMapper(IStudentDao.class);
Student student = dao.selectStudentById(2);
System.out.println(student);
sqlSession.close();
sqlSession = MyBatisUnils.getSqlSession();
dao = sqlSession.getMapper(IStudentDao.class);
Student student2 = dao.selectStudentById(2);
System.out.println(student2);
}
① 对实体进行序列化,
cache Hit Ratio 为命中率
增删改对二级缓存的影响
public void test01(){
sqlSession = MyBatisUnils.getSqlSession();
dao = sqlSession.getMapper(IStudentDao.class);
Student student = dao.selectStudentById(2);
System.out.println(student);
sqlSession.close();
sqlSession = MyBatisUnils.getSqlSession();
dao = sqlSession.getMapper(IStudentDao.class);
dao.insertStudent(new Student("",0,0));
Student student2 = dao.selectStudentById(2);
System.out.println(student2);
}
}
1.增删改同样会清空二级缓存
2.二级缓存的清空不是把
3.从DB中进行select查询的条件是:
① 缓存中根本就不存在这个key
② 缓存中存在key所对应的Entry对象,但是value为null
但不能对一级缓存进行配置
二级缓存的关闭
二级缓存的使用原则
① 多个namespace不操作同一张表
② 不要再关联关系表中做增删改操作
一个接口对应一个对象的处理,一个mapper.xml文件对应一张表的处理
③ 查询多于修改时使用二级缓存