什么是一级缓存: mybatis 默认开启一级缓存, SQLSession会话缓存, 每个SQLSession都会有各自的缓存
以下会演示一级缓存生效/失效的场景
项目地址: https://gitee.com/xmaxm/test-code/blob/master/chaim-cache/chaim-mybatis-cache/chaim-mybatis-cache-one/README.md
相关缓存文章
Mybatis的一级缓存
Mybatis的二级缓存 (默认方式)
Mybatis的二级缓存 (Redis方式)
Mybatis的二级缓存 (ehcache方式)
测试一级缓存生效, 默认开启, 需要保证在同一个 SqlSession (可使用 @Transactional 保持其同一个会话)
使用mybatis plus方法
@Transactional
public void queryingLevelCache() {LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();queryWrapper.select(SysUser::getUsername, SysUser::getPhone, SysUser::getId);queryWrapper.last("limit 1");SysUser sysUsers = sysUserMapper.selectOne(queryWrapper);log.info("查询成功, 观察日志, id: {}", sysUsers.getId());SysUser user = sysUserMapper.selectOne(queryWrapper);log.info("查询成功, 观察日志, id: {}", user.getId());
}
测试一级缓存生效, 默认开启, 需要保证在同一个 SqlSession (可使用 @Transactional 保持其同一个会话)
使用自定义SQL
@Transactionalpublic void queryingLevelCache(Integer integer) {SysUser sysUsers = sysUserMapper.selectHandwritingSql();log.info("查询成功, 观察日志, id: {}", sysUsers.getId());SysUser user = sysUserMapper.selectHandwritingSql();log.info("查询成功, 观察日志, id: {}", user.getId());}
测试一级缓存失效: 当两次查询存在之间, 存在增删改的情况
public void queryingLevelCacheFail() {LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();queryWrapper.select(SysUser::getUsername, SysUser::getPhone, SysUser::getId);queryWrapper.last("limit 1");SysUser sysUsers = sysUserMapper.selectOne(queryWrapper);log.info("查询成功, 观察日志, id: {}", sysUsers.getId());SysUser sysUser = SysUser.builder().username("潇潇").email("gmail.com").phone("000123").password("123456").sex(1).state(0).salt(1234).build();sysUserMapper.insert(sysUser);log.info("观察新增日志, id: {}", sysUsers.getPassword());SysUser user = sysUserMapper.selectOne(queryWrapper);log.info("查询成功, 观察日志, id: {}", user.getId());}
测试一级缓存失效: 当两次查询的方式不一样, 使用mybatis的方法, 以及自定义SQL
同理, 当查询的条件以及查询的内容不一致时也会失效
public void queryingLevelCacheFail(Integer integer) {LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();queryWrapper.select(SysUser::getUsername, SysUser::getPhone);queryWrapper.last("limit 1");SysUser sysUsers = sysUserMapper.selectOne(queryWrapper);log.info("查询成功, 观察日志, id: {}", sysUsers.getId());SysUser user = sysUserMapper.selectHandwritingSql();log.info("查询成功, 观察日志, id: {}", user.getId());}
测试一级缓存失效: 手动清除缓存
@Override
public void queryingLevelCacheFail(String string) {SysUser sysUsers = sysUserMapper.selectHandwritingSql();log.info("查询成功, 观察日志, id: {}", sysUsers.getId());sqlSession.clearCache();SysUser user = sysUserMapper.selectHandwritingSql();log.info("查询成功, 观察日志, id: {}", user.getId());
}
测试一级缓存失效: 去除@Transactional, 使其不在同一个 SqlSession
@Override
public void queryingLevelCacheFail(Boolean blo) {SysUser sysUsers = sysUserMapper.selectHandwritingSql();log.info("查询成功, 观察日志, id: {}", sysUsers.getId());SysUser user = sysUserMapper.selectHandwritingSql();log.info("查询成功, 观察日志, id: {}", user.getId());
}
测试一级缓存失效:
xml配置: flushCache=“true”
注解方式SQL配置: @Options(flushCache = Options.FlushCachePolicy.TRUE)
同理还可以全局配置: 禁用mybatis一级缓存: mybatis-plus.configuration.local-cache-scope: statement. 默认开始 session
@Override
public void queryingLevelCacheFail(Long lon) {SysUser sysUsers = sysUserMapper.selectHandwritingSqlFail();log.info("查询成功, 观察日志, id: {}", sysUsers.getId());SysUser user = sysUserMapper.selectHandwritingSqlFail();log.info("查询成功, 观察日志, id: {}", user.getId());log.info("-----------自义定SQL的两种失效方式-----------------");sysUsers = sysUserMapper.selectHandwritingSqlFail2();log.info("查询成功, 观察日志, id: {}", sysUsers.getId());user = sysUserMapper.selectHandwritingSqlFail2();log.info("查询成功, 观察日志, id: {}", user.getId());
}
@Options(flushCache = Options.FlushCachePolicy.TRUE)
@Select("SELECT username,phone,id FROM sys_user limit 1")
SysUser selectHandwritingSqlFail2();