1. 程式人生 > >SpringMVC +Spring + MyBatis + Mysql + Redis(作為二級緩存) 配置

SpringMVC +Spring + MyBatis + Mysql + Redis(作為二級緩存) 配置

文件 .class lose linux csdn instance 管理 total lin

轉載:http://blog.csdn.net/xiadi934/article/details/50786293

項目環境: 在SpringMVC +Spring + MyBatis + MySQL。Redis部署在Linux虛擬機。

1、整體思路

  • 參考Ehcache實現MyBatis二級緩存代碼(Maven引用對應jar查閱)
  • 使用Spring管理Redis連接池
  • 模仿EhcacheCache,實現RedisCache

2、pom.xml中加入Maven依賴

技術分享圖片
 1 <!-- spring-redis實現 -->
 2 <dependency>
 3     <groupId>org.springframework.data</groupId>
 4     <artifactId>spring-data-redis</artifactId>
 5     <version>1.6.2.RELEASE</version>
 6 </dependency>
 7 <!-- redis客戶端jar -->
 8 <dependency>
 9     <groupId>redis.clients</groupId>
10     <artifactId>jedis</artifactId>
11     <version>2.8.0</version>
12 </dependency>
13 <!-- Ehcache實現,用於參考 -->
14 <dependency>
15     <groupId>org.mybatis</groupId>
16     <artifactId>mybatis-ehcache</artifactId>
17     <version>1.0.0</version>
18 </dependency>
技術分享圖片

3、引入applicationContext.xml中引入redis配置

技術分享圖片
 1 <!-- 引入數據庫配置文件 -->
 2 <bean id="propertyConfigurer"    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
 3     <property name="locations">
 4         <list>
 5             <value>classpath:jdbc.properties</value>
 6             <value>classpath:redis.properties</value>
 7         </list>
 8     </property>
 9 </bean>
10 <!-- redis數據源 -->
11 <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">  
12     <property name="maxIdle" value="${redis.maxIdle}" />  
13     <property name="maxTotal" value="${redis.maxActive}" />  
14     <property name="maxWaitMillis" value="${redis.maxWait}" />  
15     <property name="testOnBorrow" value="${redis.testOnBorrow}" />  
16 </bean>
17 <!-- Spring-redis連接池管理工廠 -->
18 <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"  
19     p:host-name="${redis.host}" p:port="${redis.port}" p:password="${redis.pass}"  p:pool-config-ref="poolConfig"/>  
20 <!-- 使用中間類解決RedisCache.jedisConnectionFactory的靜態註入,從而使MyBatis實現第三方緩存 -->
21 <bean id="redisCacheTransfer" class="com.strive.cms.cache.RedisCacheTransfer">
22     <property name="jedisConnectionFactory" ref="jedisConnectionFactory"/>
23 </bean>
技術分享圖片

4、創建緩存實現類RedisCache

技術分享圖片
  1 /**
  2  * 
  3  * @描述: 使用第三方內存數據庫Redis作為二級緩存
  4  * @版權: Copyright (c) 2016 
  5  * @作者: xiad
  6  * @版本: 1.0 
  7  * @創建日期: 2016年3月2日 
  8  * @創建時間: 下午8:02:57
  9  */
 10 public class RedisCache implements Cache
 11 {
 12     private static final Logger logger = LoggerFactory.getLogger(RedisCache.class);
 13 
 14     private static JedisConnectionFactory jedisConnectionFactory;
 15 
 16     private final String id;
 17 
 18     /**
 19      * The {@code ReadWriteLock}.
 20      */
 21     private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
 22 
 23     public RedisCache(final String id) {
 24         if (id == null) {
 25             throw new IllegalArgumentException("Cache instances require an ID");
 26         }
 27         logger.debug("MybatisRedisCache:id=" + id);
 28         this.id = id;
 29     }
 30 
 31     @Override
 32     public void clear()
 33     {
 34         JedisConnection connection = null;
 35         try
 36         {
 37             connection = jedisConnectionFactory.getConnection();
 38             connection.flushDb();
 39             connection.flushAll();
 40         }
 41         catch (JedisConnectionException e)
 42         {
 43             e.printStackTrace();
 44         }
 45         finally
 46         {
 47             if (connection != null) {
 48                 connection.close();
 49             }
 50         }
 51     }
 52 
 53     @Override
 54     public String getId()
 55     {
 56         return this.id;
 57     }
 58 
 59     @Override
 60     public Object getObject(Object key)
 61     {
 62         Object result = null;
 63         JedisConnection connection = null;
 64         try
 65         {
 66             connection = jedisConnectionFactory.getConnection();
 67             RedisSerializer<Object> serializer = new JdkSerializationRedisSerializer();
 68             result = serializer.deserialize(connection.get(serializer.serialize(key)));
 69         }
 70         catch (JedisConnectionException e)
 71         {
 72             e.printStackTrace();
 73         }
 74         finally
 75         {
 76             if (connection != null) {
 77                 connection.close();
 78             }
 79         }
 80         return result;
 81     }
 82 
 83     @Override
 84     public ReadWriteLock getReadWriteLock()
 85     {
 86         return this.readWriteLock;
 87     }
 88 
 89     @Override
 90     public int getSize()
 91     {
 92         int result = 0;
 93         JedisConnection connection = null;
 94         try
 95         {
 96             connection = jedisConnectionFactory.getConnection();
 97             result = Integer.valueOf(connection.dbSize().toString());
 98         }
 99         catch (JedisConnectionException e)
100         {
101             e.printStackTrace();
102         }
103         finally
104         {
105             if (connection != null) {
106                 connection.close();
107             }
108         }
109         return result;
110     }
111 
112     @Override
113     public void putObject(Object key, Object value)
114     {
115         JedisConnection connection = null;
116         try
117         {
118             connection = jedisConnectionFactory.getConnection();
119             RedisSerializer<Object> serializer = new JdkSerializationRedisSerializer();
120             connection.set(serializer.serialize(key), serializer.serialize(value));
121         }
122         catch (JedisConnectionException e)
123         {
124             e.printStackTrace();
125         }
126         finally
127         {
128             if (connection != null) {
129                 connection.close();
130             }
131         }
132     }
133 
134     @Override
135     public Object removeObject(Object key)
136     {
137         JedisConnection connection = null;
138         Object result = null;
139         try
140         {
141             connection = jedisConnectionFactory.getConnection();
142             RedisSerializer<Object> serializer = new JdkSerializationRedisSerializer();
143             result =connection.expire(serializer.serialize(key), 0);
144         }
145         catch (JedisConnectionException e)
146         {
147             e.printStackTrace();
148         }
149         finally
150         {
151             if (connection != null) {
152                 connection.close();
153             }
154         }
155         return result;
156     }
157 
158     public static void setJedisConnectionFactory(JedisConnectionFactory jedisConnectionFactory) {
159         RedisCache.jedisConnectionFactory = jedisConnectionFactory;
160     }
161 
162 }
技術分享圖片

5、創建中間類RedisCacheTransfer,完成RedisCache.jedisConnectionFactory的靜態註入

技術分享圖片
 1 /**
 2  * 
 3  * @描述: 靜態註入中間類
 4  * @版權: Copyright (c) 2016 
 5  * @作者: xiad
 6  * @版本: 1.0 
 7  * @創建日期: 2016年3月2日 
 8  * @創建時間: 下午8:02:57
 9  */
10 public class RedisCacheTransfer 
11 {
12 
13     @Autowired
14     public void setJedisConnectionFactory(JedisConnectionFactory jedisConnectionFactory) {
15         RedisCache.setJedisConnectionFactory(jedisConnectionFactory);
16     }
17 
18 }
技術分享圖片

6、配置文件redis.properties

技術分享圖片
1 # Redis settings  
2 redis.host=192.168.25.132
3 redis.port=6379  
4 redis.pass=
5 
6 redis.maxIdle=300  
7 redis.maxActive=600  
8 redis.maxWait=1000  
9 redis.testOnBorrow=true 
技術分享圖片

7、mapper中加入MyBatis二級緩存

<mapper namespace="com.strive.cms.dao.site.CatalogMapper" >
  <cache type="com.strive.cms.cache.RedisCache"/>
  .....
</mapper>

8、Mybatis全局配置

技術分享圖片
 1 <?xml version="1.0" encoding="UTF-8" ?>
 2 <!DOCTYPE configuration
 3         PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
 4         "http://mybatis.org/dtd/mybatis-3-config.dtd">
 5 <configuration>
 6     <!-- 配置mybatis的緩存,延遲加載等等一系列屬性 -->
 7     <settings>
 8 
 9         <!-- 全局映射器啟用緩存 -->
10         <setting name="cacheEnabled" value="true"/>
11 
12         <!-- 查詢時,關閉關聯對象即時加載以提高性能 -->
13         <setting name="lazyLoadingEnabled" value="false"/>
14 
15         <!-- 對於未知的SQL查詢,允許返回不同的結果集以達到通用的效果 -->
16         <setting name="multipleResultSetsEnabled" value="true"/>
17 
18         <!-- 允許使用列標簽代替列名 -->
19         <setting name="useColumnLabel" value="true"/>
20 
21         <!-- 不允許使用自定義的主鍵值(比如由程序生成的UUID 32位編碼作為鍵值),數據表的PK生成策略將被覆蓋 -->
22         <setting name="useGeneratedKeys" value="false"/>
23 
24         <!-- 給予被嵌套的resultMap以字段-屬性的映射支持 FULL,PARTIAL -->
25         <setting name="autoMappingBehavior" value="PARTIAL"/>
26 
27         <!-- 對於批量更新操作緩存SQL以提高性能 BATCH,SIMPLE -->
28         <!-- <setting name="defaultExecutorType" value="BATCH" /> -->
29 
30         <!-- 數據庫超過25000秒仍未響應則超時 -->
31         <!-- <setting name="defaultStatementTimeout" value="25000" /> -->
32 
33         <!-- Allows using RowBounds on nested statements -->
34         <setting name="safeRowBoundsEnabled" value="false"/>
35 
36         <!-- Enables automatic mapping from classic database column names A_COLUMN to camel case classic Java property names aColumn. -->
37         <setting name="mapUnderscoreToCamelCase" value="true"/>
38 
39         <!-- MyBatis uses local cache to prevent circular references and speed up repeated nested queries. By default (SESSION) all queries executed during a session are cached. If localCacheScope=STATEMENT 
40             local session will be used just for statement execution, no data will be shared between two different calls to the same SqlSession. -->
41         <setting name="localCacheScope" value="SESSION"/>
42 
43         <!-- Specifies the JDBC type for null values when no specific JDBC type was provided for the parameter. Some drivers require specifying the column JDBC type but others work with generic values 
44             like NULL, VARCHAR or OTHER. -->
45         <setting name="jdbcTypeForNull" value="OTHER"/>
46 
47         <!-- Specifies which Object‘s methods trigger a lazy load -->
48         <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
49 
50         <!-- 設置關聯對象加載的形態,此處為按需加載字段(加載字段由SQL指 定),不會加載關聯表的所有字段,以提高性能 -->
51         <setting name="aggressiveLazyLoading" value="true"/>
52 
53     </settings>
54 
55 </configuration>
技術分享圖片

9、打印Sql日誌,方便測試

技術分享圖片
 1 #定義LOG輸出級別為INFO
 2 log4j.rootLogger=INFO,Console,File
 3 
 4 ####定義日誌輸出目的地為控制臺
 5 log4j.appender.Console=org.apache.log4j.ConsoleAppender
 6 log4j.appender.Console.Target=System.out
 7 #可以靈活地指定日誌輸出格式,下面一行是指定具體的格式
 8 log4j.appender.Console.layout = org.apache.log4j.PatternLayout
 9 log4j.appender.Console.layout.ConversionPattern=[%c] - %m%n
10 
11 ####文件大小到達指定尺寸的時候產生一個新的文件
12 log4j.appender.File = org.apache.log4j.RollingFileAppender
13 #指定輸出目錄
14 log4j.appender.File.File = logs/ssm.log
15 #定義文件最大大小
16 log4j.appender.File.MaxFileSize = 10MB
17 #輸出所以日誌,如果換成DEBUG表示輸出DEBUG以上級別日誌
18 log4j.appender.File.Threshold = ALL
19 log4j.appender.File.layout = org.apache.log4j.PatternLayout
20 log4j.appender.File.layout.ConversionPattern =[%p] [%d{yyyy-MM-dd HH\:mm\:ss}][%c]%m%n
21 
22 ####顯示本項目SQL語句部分
23 log4j.logger.com.strive.cms=DEBUG
技術分享圖片

10、測試代碼

技術分享圖片
 1 @RunWith(SpringJUnit4ClassRunner.class)
 2 @ContextConfiguration(locations = {"classpath:applicationContext.xml"})  
 3 public class MyBatisCacheSecondTest
 4 {
 5     private static final Logger logger = LoggerFactory.getLogger(MyBatisCacheSecondTest.class);    
 6 
 7     @Autowired
 8     private  SiteService service;
 9 
10     /*
11      * 二級緩存測試
12      */
13     @Test
14     public void testCache2() {
15         PageInfo<Site> page1 = service.querySite("", 1, 2, "", "");
16         logger.info(page1.getList().get(1).getName());
17 
18         PageInfo<Site> page2 = service.querySite("", 2, 2, "", "");
19         logger.info(page2.getList().get(0).getName());
20 
21         PageInfo<Site> page3 = service.querySite("", 1, 2, "", "");
22         logger.info(page3.getList().get(0).getName());
23     }   
24 
25 }
技術分享圖片

首次運行結果
技術分享圖片
後續運行結果
技術分享圖片
同條件的查詢語句可以發現,已經不再查詢Mysql,而是直接取Redis數據
查看Redis數據庫 keys *, 會發現多了很多數據,結果如下
技術分享圖片
至此,Redis基本配置成功。

SpringMVC +Spring + MyBatis + Mysql + Redis(作為二級緩存) 配置