缓存的作用
缓存(cache)的作用是为了减轻数据库的压力,提高查询性能。
为什么使用缓存
mysql数据库保存的数据均在硬盘中,CPU是不会直接和硬盘进行交互的,因为硬盘的数据传输率很低,而CPU的数据传输率很高, CPU和内存直接进行交互,内存的数据传输速率更快。例如,在短时间内,当需要对数据库进行多次同一访问操作时,整个过程中就需要多次获取存储在硬盘中数据,由上文可知,获取硬盘的数据速度较慢,我们可以将第一次访问后得到的数据放入缓存(cache)中,缓存是在内存当中,下一次访问时直接从缓存中获取,也就是从内存中获取,而不是硬盘中。从而减少了对数据库的查询次数,因此提高了数据库的性能。
一级缓存和二级缓存
一级缓存
一级缓存作用域是同一个SqlSession对象,即一次sql会话,在一个sql会话中执行多次相同的sql语句,第一次执行完毕后会将数据库中查询到的数据放入到缓存中,在本次sql会话中执行重复的sql操作,会直接从缓存中获取数据。
由于SqlSession对象在每次执行完毕后都会关闭,所以一级缓存并无实际意义。
代码示例:
import com.flash.mybatis.dao.StudentDao;
import com.flash.mybatis.util.MybatisUtil;
import org.apache.ibatis.session.SqlSession;
/**
* @author flash
* @date 2024/06/22 9:51
* 功能描述:mybatis一级缓存
*/
public class Test {
public static void main(String[] args) {
SqlSession sqlSession = MybatisUtil.sqlSessionFactory.openSession();
StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
studentDao.findStudentById(1);
studentDao.findStudentById(1);
sqlSession.close();
}
}
运行结果:
清空一级缓存
方法①:执行增、删、改操作
方法②:调用SqlSession对象的clearCache()方法
方法③:关闭本次sql会话,即执行SqlSession对象的close()方法
代码示例:
import com.flash.mybatis.dao.StudentDao;
import com.flash.mybatis.util.MybatisUtil;
import org.apache.ibatis.session.SqlSession;
/**
* @author flash
* @date 2024/06/22 9:51
* 功能描述:mybatis一级缓存
*/
public class Test {
public static void main(String[] args) {
SqlSession sqlSession = MybatisUtil.sqlSessionFactory.openSession();
StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
// mybatis 提供的缓存功能
// 一级缓存, 作用不太大
// 同一个 sqlSession 会话中相同的查询语句, 只执行一次, 然后将数据放入缓存中
// 下次再取时直接从 sqlSession 缓存中获取
studentDao.findStudentById(1);
// 方法1.中间如果含有增删改操作, 则会清空一级缓存数据
// studentDao.deleteStudentById(1);
// 方法2.或强制清空一级缓存
sqlSession.clearCache();
studentDao.findStudentById(1);
// 方法3.关闭sql会话清空当前 sqlSession 一级缓存
sqlSession.close();
}
}
执行结果:
由运行结果可知,执行了两次sql语句
二级缓存
二级缓存是多个SqlSession对象所共享的,作用域是同一个SqlSessionFactory对象,短时间内不同的sql会话中执行相同的sql语句,除第一次外可以直接从缓存中获取数据。Mybatis中默认没有开启缓存开启二级缓存,需要在Mybatis的配置文件中在<setting>标签中设置全局参数开启二级缓存。
mybatis配置文件设置如图所示
映射文件设置cache属性如图所示
使用cache的类需要实现Serializable接口,定义serialVersionUID
代码示例:
import com.flash.mybatis.dao.StudentDao;
import com.flash.mybatis.util.MybatisUtil;
import org.apache.ibatis.session.SqlSession;
/**
* @author flash
* @date 2024/06/22 10:39
* 功能描述:mybatis提供的二级缓存
*/
public class Test {
public static void main(String[] args) {
SqlSession sqlSession = MybatisUtil.sqlSessionFactory.openSession();
// sqlSessionFactory 对象只有一个, 创建后不关闭, 多个 sqlSession
StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
studentDao.findStudentById(1);
sqlSession.close();
SqlSession sqlSession2 = MybatisUtil.sqlSessionFactory.openSession();
// 此处可以打断点, 缓存刷新设置的是 3s, debug停在断点处 3s 过后就会第二次重复查询, 因为缓冲区上一次放入的数据已经被清空
StudentDao studentDao2 = sqlSession2.getMapper(StudentDao.class);
studentDao2.findStudentById(1);
sqlSession2.close();
}
}
运行结果: