缓存的优点在于能够加快查询的速度,在数据库查询的情景之下,在需要多次执行同一sql(sql语句相同,参数相同)的情况下,如果能将查询的结果缓存下来就不需要每次都到数据库上去真正执行查询语句,显然能加快查询速度。mybatis提供了缓存机制,分为系统缓存和开发人员自定义的缓存。
1.系统缓存
mybatis提供缓存支持,但是默认情况下只开启一级缓存,所谓的一级缓存是针对单个sqlSession(和数据的一次会话)而言的。具体来说,通过同一个sqlSession获取的同一个Mapper对象多次执行参数和SQL都一样的语句,则只有第一次执行的时候会被发送到数据库上去执行,然后将结果放到缓存中去,后面都会从mybatis的缓存中直接取结果,当然如果缓存超时还是会再去数据库执行一次。
下面的代码对一级缓存进行了测试,可以看到对于同个sqlSession获得的相同Mapper对象,多次执行同一查询结时只有第一次查询会真正走数据库;如果换个SqlSession,则又会重新走数据库进行查询。
测试代码:
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory sessionFactory = builder.build(Resources.getResourceAsStream("mybatis-config.xml"), "test");
SqlSession sqlSession = sessionFactory.openSession();
PersonDao personDao = sqlSession.getMapper(PersonDao.class);
//三次循环实际上只需要执行一次查询
for (int i = 0; i < 3; i++) {
System.out.println(personDao.queryPersonById(6));
}
//使用二级缓存时,sqlSession调用了commit才会生效
sqlSession.commit();
//换一个sqlSession,就不能再走缓存
SqlSession sqlSession1 = sessionFactory.openSession();
PersonDao personDao1 = sqlSession1.getMapper(PersonDao.class); System.out.println(personDao1.queryPersonById(6));
测试结果输出(使用log4j输出的mybatis日志):
11:37:49.543 DEBUG (JakartaCommonsLoggingImpl.java:54) - Logging initialized using 'class org.apache.ibatis.logging.commons.JakartaCommonsLoggingImpl' adapter.
11:37:49.631 DEBUG (LogFactory.java:135) - Logging initialized using 'class org.apache.ibatis.logging.log4j.Log4jImpl' adapter.
11:37:49.757 DEBUG (JdbcTransaction.java:136) - Opening JDBC Connection
11:37:50.026 DEBUG (JdbcTransaction.java:100) - Setting autocommit to false