数据库的大部分场景下是从磁盘读取,如果数据从内存进行读取,速度较比磁盘要快得多。但因为内存的容量有限,所以一般只会把使用和查询较多的数据缓存起来,以便快速反应,其他使用率不太多的继续存放在磁盘。
mybatis分为一级缓存和二级缓存
1.一级缓存
一级缓存存放在SqlSqeeion上,默认开启
1.1pojo
@Data
public class Role{
private Long id;
private String roleName;
private String note;
}1.2Mapper
public interface RoleMapper {
Role getRole (long id);
}1.3xml文件
<mapper namespace="mybatis04.mapper.RoleMapper">
<select id="getRole" resultType="role">
select id,role_name as roleName,note from t_role where id=#{id}
</select>
</mapper>1.4测试一级缓存
public class Mybatis04Test {
public static void main(String[] args) {
getRole();
}
public static void getRole(){
SqlSession sqlSession=null;
try {
Logger logger = Logger.getLogger(Mybatis04Test.class);
sqlSession = SqlSessionFactoryUtils.openSqlSession();
RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class);
Role role=roleMapper.getRole(1l);
logger.debug("获取pojo对象"+role);
RoleMapper roleMapper1=sqlSession.getMapper(RoleMapper.class);
Role role1=roleMapper1.getRole(1l);
logger.debug("同SqlSession获取pojo对象"+role1);
} catch (Exception ex) {
ex.printStackTrace();
} finally {
if (sqlSession != null) {
sqlSession.close();
}
}
}
}执行查看日志

发现虽然出现两个结果,但是sql却只出现了一条,mybatis的一级缓存存在于SqlSession中,如果SqlSession第一次通过sql和参数获取对象后就会将其缓存,第二次查询如果sql和参数没有变化就会从缓存中获取数据,不会再次连接数据库。
1.5使用不同SqlSession测试
public class Mybatis04Test {
public static void main(String[] args) {
getRole();
}
public static void getRole(){
SqlSession sqlSession=null;
SqlSession sqlSession1=null;
try {
Logger logger = Logger.getLogger(Mybatis04Test.class);
sqlSession = SqlSessionFactoryUtils.openSqlSession();
RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class);
Role role=roleMapper.getRole(1l);
logger.debug("获取pojo对象"+role);
RoleMapper roleMapper1=sqlSession.getMapper(RoleMapper.class);
Role role1=roleMapper1.getRole(1l);
logger.debug("同SqlSession获取pojo对象"+role1);
sqlSession.close();
//不同SqlSession获取pojo
sqlSession1=SqlSessionFactoryUtils.openSqlSession();
RoleMapper roleMapper2=sqlSession1.getMapper(RoleMapper.class);
Role role2=roleMapper2.getRole(1l);
logger.debug("不同SqlSession获取pojo"+role2);
} catch (Exception ex) {
ex.printStackTrace();
} finally {
if (sqlSession != null) {
sqlSession.close();
}
}
}
}查看日志

发现日志中出现两条sql,此测试可以确定一级缓存是存在在SqlSession中的,
2.二级缓存
二级缓存存放在SqlSessionFactory需要通过配置开启,并且POJO对象需要实现序列化接口
2.1配置二级缓存

配置二级缓存很简单,在xml文件中加入<cache/>元素即可

POJO对象实现序列化接口
2.2测试二级缓存
public class Mybatis04Test {
public static void main(String[] args) {
getRole();
}
public static void getRole(){
SqlSession sqlSession=null;
SqlSession sqlSession1=null;
try {
Logger logger = Logger.getLogger(Mybatis04Test.class);
sqlSession = SqlSessionFactoryUtils.openSqlSession();
RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class);
Role role=roleMapper.getRole(1l);
logger.debug("获取pojo对象"+role);
RoleMapper roleMapper1=sqlSession.getMapper(RoleMapper.class);
Role role1=roleMapper1.getRole(1l);
logger.debug("同SqlSession获取pojo对象"+role1);
sqlSession.commit();
//不同SqlSession获取pojo
sqlSession1=SqlSessionFactoryUtils.openSqlSession();
RoleMapper roleMapper2=sqlSession1.getMapper(RoleMapper.class);
Role role2=roleMapper2.getRole(1l);
sqlSession1.commit();
logger.debug("不同SqlSession获取pojo"+role2);
} catch (Exception ex) {
ex.printStackTrace();
} finally {
if (sqlSession != null) {
sqlSession.close();
}
}
}
}测试二级缓存需要commit提交,如果不提交是不会保存到二级缓存的
2.3查看日志
日志中三个结果只有一条sql,证明是从SqlSessionFactory获取缓存
缓存失效
对数据进行INSERT,UPDATE,DELETE,或者清除缓存都会造成缓存失效
版权声明:本文为m0_56058975原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。