mybatis的缓存技术使用
一级缓存的作用域仅限于一个sqlsession,但是二级缓存的作用域是一个namespace。
这里的原则是,如果开启了二级缓存,那么在关闭sqlsession后,会把该sqlsession一级缓存中的数据添加到namespace的二级缓存中
默认所有的查询都会加入缓存,所有的增删改都会更新缓存
1 long beginTime = System.nanoTime(); 2 TestMybatis testMybatis = this.testMybatisMapper.selectByPrimaryKey(new BigDecimal("1")); 3 long endTime = System.nanoTime(); 4 System.out.println("查询时间 :" + (endTime - beginTime) + "ns"); 5 System.out.println("姓名:" + testMybatis.getTid()); 6 TestMybatis testMybatis2 = this.testMybatisMapper.selectByPrimaryKey(new BigDecimal("1")); 7 System.out.println("姓名:" + testMybatis2.getTid());
1 [service] 2016-08-29 07:48:49,951 - org.springframework.jdbc.datasource.DataSourceUtils -1626 [main] DEBUG org.springframework.jdbc.datasource.DataSourceUtils - Fetching JDBC Connection from DataSource 2 [service] 2016-08-29 07:48:50,132 - org.mybatis.spring.transaction.SpringManagedTransaction -1807 [main] DEBUG org.mybatis.spring.transaction.SpringManagedTransaction - JDBC Connection [jdbc:oracle:thin:@127.0.0.1:1521:hellowang, UserName=LIHU, Oracle JDBC driver] will not be managed by Spring 3 [service] 2016-08-29 07:48:50,140 - com.erp.dao.TestMybatisMapper.selectByPrimaryKey -1815 [main] DEBUG com.erp.dao.TestMybatisMapper.selectByPrimaryKey - ==> Preparing: select TID, TNAME from TESTMYBATIS where TID = ? 4 [service] 2016-08-29 07:48:50,230 - com.erp.dao.TestMybatisMapper.selectByPrimaryKey -1905 [main] DEBUG com.erp.dao.TestMybatisMapper.selectByPrimaryKey - ==> Parameters: 1(BigDecimal) 5 [service] 2016-08-29 07:48:50,285 - com.erp.dao.TestMybatisMapper.selectByPrimaryKey -1960 [main] DEBUG com.erp.dao.TestMybatisMapper.selectByPrimaryKey - <== Total: 1 6 [service] 2016-08-29 07:48:50,288 - org.mybatis.spring.SqlSessionUtils -1963 [main] DEBUG org.mybatis.spring.SqlSessionUtils - Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@72cb3389] 7 [service] 2016-08-29 07:48:50,288 - org.springframework.jdbc.datasource.DataSourceUtils -1963 [main] DEBUG org.springframework.jdbc.datasource.DataSourceUtils - Returning JDBC Connection to DataSource 8 查询时间 :354391649ns 9 姓名:1 10 [service] 2016-08-29 07:48:50,288 - org.mybatis.spring.SqlSessionUtils -1963 [main] DEBUG org.mybatis.spring.SqlSessionUtils - Creating a new SqlSession 11 [service] 2016-08-29 07:48:50,288 - org.mybatis.spring.SqlSessionUtils -1963 [main] DEBUG org.mybatis.spring.SqlSessionUtils - SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@26b40593] was not registered for synchronization because synchronization is not active 12 [service] 2016-08-29 07:48:50,288 - com.erp.dao.TestMybatisMapper -1963 [main] DEBUG com.erp.dao.TestMybatisMapper - Cache Hit Ratio [com.erp.dao.TestMybatisMapper]: 0.5 13 [service] 2016-08-29 07:48:50,288 - org.mybatis.spring.SqlSessionUtils -1963 [main] DEBUG org.mybatis.spring.SqlSessionUtils - Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@26b40593] 14 姓名:1 15 [service] 2016-08-29 07:48:50,290 - org.springframework.test.context.support.DirtiesContextTestExecutionListener -1965 [main] DEBUG org.springframework.test.context.support.DirtiesContextTestExecutionListener - After test method: context [DefaultTestContext@4d560eeb testClass = TestEv, testInstance = com.erp.test.TestEv@4ced8df7, testMethod = tcache@TestEv, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@37a96 testClass = TestEv, locations = '{classpath:spring-mybatis.xml}', classes = '{}', contextInitializerClasses = '[]', activeProfiles = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]], class dirties context [false], class mode [null], method dirties context [false]. 16 [service] 2016-08-29 07:48:50,291 - org.springframework.test.context.support.DirtiesContextTestExecutionListener -1966 [main] DEBUG org.springframework.test.context.support.DirtiesContextTestExecutionListener - After test class: context [DefaultTestContext@4d560eeb testClass = TestEv, testInstance = [null], testMethod = [null], testException = [null], mergedContextConfiguration = [MergedContextConfiguration@37a96 testClass = TestEv, locations = '{classpath:spring-mybatis.xml}', classes = '{}', contextInitializerClasses = '[]', activeProfiles = '{}', contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]], dirtiesContext [false]. 17
可见我们在第二次查询的时候并没有发出sql
二级缓存
开启mybatis的二级缓存其实和hibernate的差不多,如果我们去整合spring的话
1 <!-- https://mvnrepository.com/artifact/org.mybatis.caches/mybatis-ehcache --> 2 <dependency> 3 <groupId>org.mybatis.caches</groupId> 4 <artifactId>mybatis-ehcache</artifactId> 5 <version>1.0.1</version> 6 </dependency> 7 <!-- https://mvnrepository.com/artifact/net.sf.ehcache/ehcache-core --> 8 <dependency> 9 <groupId>net.sf.ehcache</groupId> 10 <artifactId>ehcache-core</artifactId> 11 <version>2.4.6</version> 12 </dependency>
然后在spring-mybatis.xml全局设置一下
1 <!-- 使用ehcache缓存 --> 2 <bean id="ehCacheManager" 3 class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"> 4 <property name="configLocation" value="classpath:ehcache.xml" /> 5 </bean>
然后再在mapper文件里加入
1 <cache type="org.mybatis.caches.ehcache.LoggingEhcache" > 2 <property name="timeToIdleSeconds" value="3600"/> 3 <property name="timeToLiveSeconds" value="3600"/> 4 <property name="maxEntriesLocalHeap" value="1000"/> 5 <property name="maxEntriesLocalDisk" value="10000000"/> 6 <property name="memoryStoreEvictionPolicy" value="LRU"/> 7 </cache>
这样默认就把这个mapper下所有的CRUD都加入了缓存如果我们想在某个方法上关掉缓存也可以在接口文件上
package com.erp.dao; import com.erp.model.TestMybatis; import java.math.BigDecimal; import org.apache.ibatis.annotations.Options; import org.springframework.stereotype.Repository; @Repository public interface TestMybatisMapper { int deleteByPrimaryKey(BigDecimal tid); int insert(TestMybatis record); int insertSelective(TestMybatis record); @Options(useCache = false, timeout = 10000, flushCache = false) TestMybatis selectByPrimaryKey(BigDecimal tid); int updateByPrimaryKeySelective(TestMybatis record); int updateByPrimaryKey(TestMybatis record); }
下面是测试代码
1 package com.erp.test; 2 3 import java.math.BigDecimal; 4 5 import org.junit.Test; 6 import org.junit.runner.RunWith; 7 import org.springframework.beans.factory.annotation.Autowired; 8 import org.springframework.test.context.ContextConfiguration; 9 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 10 11 import com.erp.dao.TestMybatisMapper; 12 import com.erp.model.TestMybatis; 13 14 @RunWith(SpringJUnit4ClassRunner.class) 15 @ContextConfiguration(locations = { "classpath:spring-mybatis.xml" }) 16 public class TestEv { 17 18 @Autowired 19 TestMybatisMapper testMybatisMapper; 20 21 @Test 22 public void tcache() { 23 // TestMybatis record = new TestMybatis(); 24 // BigDecimal tid = new BigDecimal("2"); //贷款金额 25 // record.setTid(tid); 26 // record.setTname("张三"); 27 // this.testMybatisMapper.insert(record ); 28 29 long beginTime = System.nanoTime(); 30 TestMybatis testMybatis = this.testMybatisMapper.selectByPrimaryKey(new BigDecimal("1")); 31 long endTime = System.nanoTime(); 32 System.out.println("查询时间 :" + (endTime - beginTime) + "ns"); 33 System.out.println("姓名:" + testMybatis.getTid()); 34 TestMybatis testMybatis2 = this.testMybatisMapper.selectByPrimaryKey(new BigDecimal("1")); 35 System.out.println("姓名:" + testMybatis2.getTid()); 36 } 37 } 38 /**关闭缓存 开启缓存 39 * 340388261ns 292857615ns--- 40 * 285626842ns 329079631ns--- 41 * 323713924ns 334840685ns--- 42 * 326073275ns 323204038ns--- 43 */
似乎开缓存没什么卵用对吧,
其实我也是这么想,但是反过来想想我们用junit测试这样每次都加载配置文件是不是就相当于每次都是重启服务器啊
所以下面是在springmvc环境下测试的,而且在日志里也明确看到了在重启服务有clearcache的日志打印
1 /** 2 * 392194036ns 662608ns--- 3 * 285626842ns 573111ns--- 4 * 323713924ns 7278422ns---6 */
1 package com.erp.controller; 2 3 import java.math.BigDecimal; 4 5 import org.springframework.beans.factory.annotation.Autowired; 6 import org.springframework.web.bind.annotation.RequestMapping; 7 import org.springframework.web.bind.annotation.RestController; 8 9 import com.erp.dao.TestMybatisMapper; 10 import com.erp.model.TestMybatis; 11 12 @RestController 13 public class Helloworld { 14 15 @Autowired 16 TestMybatisMapper testMybatisMapper; 17 18 @RequestMapping("1") 19 public void hello() { 20 long beginTime = System.nanoTime(); 21 TestMybatis testMybatis = this.testMybatisMapper.selectByPrimaryKey(new BigDecimal("1")); 22 long endTime = System.nanoTime(); 23 System.out.println("查询时间 :" + (endTime - beginTime) + "ns"); 24 System.out.println("姓名:" + testMybatis.getTid()); 25 TestMybatis testMybatis2 = this.testMybatisMapper.selectByPrimaryKey(new BigDecimal("1")); 26 System.out.println("姓名:" + testMybatis2.getTid()); 27 } 28 }
另外附上几个有用的链接
mybatis和redis实现缓存技术
http://blog.csdn.net/xiadi934/article/details/50786293
mybatis缓存技术加与sprigmvc整合