- 1.一级缓存
- 2.二级缓存
- 3.案例
- 一级缓存测试:
- 二级缓存测试:
Mybatis默认开启一级缓存,不需要我们额外配置。
一级缓存的对象为SqlSession对象,每个SqlSession对象都有缓存区,同一个SqlSession对象获取到的mapper映射器多次执行相同的查询只会对数据库查询一次。
一级缓存清空的时机:对数据库执行,增/删/改/事务提交(commit())/关闭close()时,一级缓存清空
2.二级缓存Mybatis二级缓存的开启需要我们手动配置,二级缓存的对象为SqlSessionFactory,它存在于处理器的高速缓存(cache)中,注意:二级缓存的时数据,而不是对象,sqlSession取到数据后,会调用构造方法创建新的对象,然后把数据封装到对象中,所以我们得到的对象,地址不同。
-
mybatis核心配置文件
-
-
映射文件中声明
-
-
映射文件中方法声明
-
select * from myb_test
-
查询数据中所有的用户,从而观察一级缓存和二级缓存
log4j日志文件:log4j日志是为了方便我们对数据库方法进行观察
-
maven
-
org.mybatis mybatis 3.5.7 org.projectlombok lombok 1.18.22 mysql mysql-connector-java 8.0.27 log4j log4j 1.2.17
-
-
User.class
-
@Data @ToString public class User implements Serializable { private int id; private String name; private int age; private Date birthday; }
-
-
UserDao.class
-
public interface UserDao { ListselectAll(); }
-
-
UserMapper.xml
-
-
mybatis-config.xml
-
-
测试类
-
public class UserDaoTest { private SqlSessionFactory factory = null; private InputStream in = null; @Before public void init() throws IOException { in = Resources.getResourceAsStream("mybatis-config.xml"); factory = new SqlSessionFactoryBuilder().build(in); } @Test public void secondCache(){ SqlSession sqlSession1 = factory.openSession(); SqlSession sqlSession2 = factory.openSession(); SqlSession sqlSession3 = factory.openSession(); sqlSession1.getMapper(UserDao.class).selectAll(); sqlSession1.close(); //注意这里要close()清空一级缓存 sqlSession2.getMapper(UserDao.class).selectAll(); sqlSession2.close();//注意这里要close()清空一级缓存 sqlSession3.getMapper(UserDao.class).selectAll(); sqlSession3.close();//注意这里要close()清空一级缓存 } @Test public void firstCache(){ SqlSession sqlSession = factory.openSession(); UserDao userDao = sqlSession.getMapper(UserDao.class); Listusers1 = userDao.selectAll(); List users2 = userDao.selectAll(); System.out.println(users1 == users2); } @After public void destroy() throws IOException { in.close(); } }
-
-
log4j.xml
-
# Set root category priority to INFO and its only appender to CONSOLE. #log4j.rootCategory=INFO, ConSOLE debug info warn error fatal log4j.rootCategory=debug, CONSOLE, LOGFILE # Set the enterprise logger category to FATAL and its only appender to CONSOLE. log4j.logger.org.apache.axis.enterprise=FATAL, ConSOLE # ConSOLE is set to be a ConsoleAppender using a PatternLayout. log4j.appender.ConSOLE=org.apache.log4j.ConsoleAppender log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %mn # LOGFILE is set to be a File appender using a PatternLayout. log4j.appender.LOGFILE=org.apache.log4j.FileAppender log4j.appender.LOGFILE.File=D:log log4j.appender.LOGFILE.Append=true log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %mn
-
从结果可以看出,两次查询只对数据库访问一次,且user2 == user1 结果为true,说明第二次查询是从sqlSession缓存中取数据的。
二级缓存测试:虽然我们时使用sqlSession1,sqlSession2,sqlSession3对象都执行一次查询,但是从日志上可以看到,对数据库只执行了一次查询,说明第二和第三次查询操作都是从二级缓存之中获取数据的。



