package com.zzw.mapper;
import com.zzw.entity.Monster;
import com.zzw.util.MyBatisUtils;
import org.apache.ibatis.cache.impl.PerpetualCache;
import org.apache.ibatis.session.SqlSession;
import org.junit.Before;
import org.junit.Test;
/**
* @author 赵志伟
* @version 1.0
*/
@SuppressWarnings({"all"})
public class MonsterMapperTest {
//属性
private SqlSession sqlSession;
private MonsterMapper monsterMapper;
/**
* 解读
* 1. 编写方法完成初始化
* 2. 当方法标注 @Before, 表示在执行你的目标测试方法前, 会先执行该方法
* 3. 这里在测试的时候, 可能小伙伴们会遇到一些麻烦, 老师说了解决方案
*/
@Before
public void init() {
//获取到sqlSession
sqlSession = MyBatisUtils.getSqlSession();
//获取到MonsterMapper对象 monsterMapper=class com.sun.proxy.$Proxy7 代理对象
//, 底层是使用了动态代理机制, 后面我们自己实现mybatis底层机制时, 会讲到
monsterMapper = sqlSession.getMapper(MonsterMapper.class);
System.out.println("monsterMapper=" + monsterMapper.getClass());
}
@Test
public void getMonsterById() {
Monster monster = monsterMapper.getMonsterById(7);
System.out.println("monster=" + monster);
//查询语句, 释放连接还是有必要的
if (sqlSession != null) {
sqlSession.close();
}
System.out.println("查询成功");
}
//测试一级缓存
@Test
public void level1CacheTest() {
//查询id=7的monster
Monster monster = monsterMapper.getMonsterById(7);
System.out.println("monster=" + monster);
monsterMapper.getMonsterById(8);//不会返回值也会存到一级缓存里
//查询id=7的monster
//当我们再次查询 id=7的Monster时, 直接从一级缓存获取, 不会再次发出sql
System.out.println("---因为一级缓存默认是打开的, 当你再次查询相同的id时, 不会再发出sql---");
Monster monster2 = monsterMapper.getMonsterById(7);
System.out.println("monster2=" + monster);
if (sqlSession != null) {
sqlSession.close();
}
}
//测试一级缓存,失效
//关闭sqlSession会话后, 一级缓存失效
@Test
public void level1CacheTest2() {
//查询id=7的monster
Monster monster = monsterMapper.getMonsterById(7);
System.out.println("monster=" + monster);
//关闭sqlSession, 一级缓存失效
if (sqlSession != null) {
sqlSession.close();
}
//因为关闭了sqlSession, 所以需要重新初始化sqlSession和 monsterMapper
sqlSession = MyBatisUtils.getSqlSession();
monsterMapper = sqlSession.getMapper(MonsterMapper.class);
//查询id=7的monster
//当我们再次查询 id=7的Monster时, 直接从一级缓存获取, 不会再次发出sql
System.out.println("---如果你关闭了sqlSession, 当你再次查询相同的id时, 仍然会发出sql---");
Monster monster2 = monsterMapper.getMonsterById(7);
System.out.println("monster2=" + monster);
if (sqlSession != null) {
sqlSession.close();
}
}
//测试一级缓存,失效
//如果执行sqlSession.clearCache(), 会导致一级缓存失效
@Test
public void level1CacheTest3() {
//查询id=7的monster
Monster monster = monsterMapper.getMonsterById(7);
System.out.println("monster=" + monster);
//执行clearCache
/**
* @Override
* public void clearCache() {
* executor.clearLocalCache();
* }
*/
sqlSession.clearCache();
//查询id=7的monster
System.out.println("---如果你执行了sqlSession.clearCache(), 当你再次查询相同的id时, 仍然会发出sql---");
Monster monster2 = monsterMapper.getMonsterById(7);
System.out.println("monster2=" + monster);
if (sqlSession != null) {
sqlSession.close();
}
}
//测试一级缓存,失效
//如果修改了同一个对象, 会导致一级缓存[对象数据]失效
@Test
public void level1CacheTest4() {
//查询id=7的monster
Monster monster = monsterMapper.getMonsterById(7);
System.out.println("monster=" + monster);
//如果修改了同一个对象, 会导致一级缓存[对象数据]失效
monster.setName("赵志伟^_^");
monsterMapper.updateMonster(monster);
//查询id=7的monster
System.out.println("---如果你修改了同一个对象, 当你再次查询相同的id时, 仍然会发出sql---");
Monster monster2 = monsterMapper.getMonsterById(7);
System.out.println("monster2=" + monster);
if (sqlSession != null) {
sqlSession.commit();//这里需要commit
sqlSession.close();
}
}
//测试二级缓存的使用
@Test
public void level2CacheTest() {
//查询id=7的monster
Monster monster = monsterMapper.getMonsterById(7);
System.out.println("monster=" + monster);
//这里我们关闭sqlSession
if (sqlSession != null) {
sqlSession.close();
}
//重新获取sqlSession
sqlSession = MyBatisUtils.getSqlSession();
//重新获取了monsterMapper
monsterMapper = sqlSession.getMapper(MonsterMapper.class);
//查询id=7的monster
System.out.println("---虽然前面关闭了sqlSession, 因为配置二级缓存, " +
"当你再次查询相同的id时, 依然不会再发出sql, 而是从二级缓存获取---");
Monster monster2 = monsterMapper.getMonsterById(7);
System.out.println("monster2=" + monster);
Monster monster3 = monsterMapper.getMonsterById(7);
System.out.println("monster3=" + monster3);
if (sqlSession != null) {
sqlSession.close();
}
}
//演示:二级缓存->一级缓存->DB执行的顺序
@Test
public void cacheSeqTest() {
System.out.println("查询第1次");
//DB, 会发出sql, 分析cache hit radio 0.0
Monster monster1 = monsterMapper.getMonsterById(7);
System.out.println(monster1);
//这里我们关闭sqlSession, 一级缓存数据消失
//当我们关闭一级缓存的时候, 如果你配置了二级缓存, 那么一级缓存的数据, 会放入到二级缓存
sqlSession.close();
sqlSession = MyBatisUtils.getSqlSession();
monsterMapper = sqlSession.getMapper(MonsterMapper.class);
System.out.println("查询第2次");
//从二级缓存获取id=7 monster信息, 就不会发出sql, cache hit radio 0.5
Monster monster2 = monsterMapper.getMonsterById(7);
System.out.println(monster2);
System.out.println("查询第3次");
//从二级缓存获取id=7 monster信息, 就不会发出sql, cache hit radio 0.666666
Monster monster3 = monsterMapper.getMonsterById(7);
System.out.println(monster3);
if (sqlSession != null) {
sqlSession.close();
}
}
//分析缓存执行顺序
//二级缓存->一级缓存->DB
@Test
public void cacheSeqTest2() {
System.out.println("查询第1次");
//DB, 会发出sql, 分析cache hit radio 0.0
Monster monster1 = monsterMapper.getMonsterById(7);
System.out.println(monster1);
//这里没有关闭sqlSession
System.out.println("查询第2次");
//从一级缓存获取id=7, cache hit radio 0.0, 不�