一、缓存概念
1.什么是缓存?
1.存储在内存当中的数据。
2.将用户常使用的数据存放在缓存(内存)当中,用户查询数据就不用从磁盘(关系型数据库文件)当中查询,从缓存当中查询,从而提高查询效率,解决了高并发系统的性能问题。
2.缓存的作用
减少和数据库的交互次数,减少系统开销,提高系统效率。
3.使用场景
经常查询并且不长改变的数据。
二、Mybatis缓存
mybatis包含了一个非常强大的查询缓存特性,他可以非常方便的定制和配置缓存。缓存可以极大的提高查询的效率。
mybatis系统当中默认定义了两级缓存:一级缓存和二级缓存:
默认情况之下,只有一级缓存开启(sqlSession级别的缓存)二级缓存需要手动开启配置,需要局域namespace级别的缓存。
1.一级缓存(本地缓存)
与数据库同一次会话期间查询到的数据会放入的本地缓存当中。
如果以后需要获取相同的数据直接去缓存当中拿,没必要再去查询数据库。
public class UserTest {
private InputStream in = null;
private SqlSession session = null;
private UserDao mapper = null;
/**
* 测试查询所有的方法
*/
@Test
public void findById() throws IOException {
//加载主配置文件,目的是为了构建SqlSessionFactory对象
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//创建SqlSessionFactory对象
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
//通过SqlSessionFactory工厂对象创建SqlSesssion对象
session = factory.openSession();
//通过Session创建UserDao接口代理对象
mapper = session.getMapper(UserDao.class);
User user1 = mapper.findById(1);
System.out.println(user1.toString());
System.out.println("-----------------");
User user2 = mapper.findById(1);
System.out.println(user2.toString());
System.out.println(user1 == user2);
//释放资源
session.close();
in.close();
}
}
通过日志可以发现sql语句只执行了一次。
2. 一级缓存失效的情况
1.sqlSession不同
2.sqlSession相同,查询条件不同
3.sqlSession相同,两次查询之间执行了增删改操作
4.sqlSession相同,手动清除一级缓存
3.二级缓存
1. 在SqlMapConfig.xml配置文件中开启二级缓存
<!‐‐ 开启二级缓存 ‐‐>
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
2. 在UserDao.xml配置文件声明使用二级缓存
<!--使用二级缓存--> <cache eviction="FIFO" flushInterval="6000" size="512" readOnly="true"/>
3.在select标签上使用二级缓存
<select id="findById" parameterType="int" resultType="User" useCache="true" >
select * from user where id = #{id}
</select>
4.测试
public class UserTest {
private InputStream in = null;
private SqlSession session = null;
private UserDao mapper = null;
/**
* 测试查询所有的方法
*/
@Test
public void findById() throws IOException {
//加载主配置文件,目的是为了构建SqlSessionFactory对象
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//创建SqlSessionFactory对象
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
//通过SqlSessionFactory工厂对象创建SqlSesssion对象
session = factory.openSession();
//通过Session创建UserDao接口代理对象
mapper = session.getMapper(UserDao.class);
User user1 = mapper.findById(1);
System.out.println(user1.toString());
System.out.println("-----------------");
session.commit();
System.out.println("-----------------");
User user2 = mapper.findById(1);
System.out.println(user2.toString());
System.out.println(user1 == user2);
//释放资源
session.close();
in.close();
}
}
5. 打印发现2个对象的地址值不一样,但是确实只发送了一次SQL语句的查询,二级缓存中存储的是数据,不是对象。
6. 二级缓存的生效必须要调用session.commit()或者session.close()方法才能生效。