一級緩存的作用域僅限於一個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整合