SSM專案整合Redis(cache)
阿新 • • 發佈:2019-02-20
本文主要講解如何在現有的SSM(Spring + SpringMVC + Mybatis)專案下,整合Redis作為二級快取,本文使用的是mysql資料庫。
準備工作:
·完整的SSM專案;
·已安裝好的Redis支援
整合過程:
1、在原來的專案中新增相關的jar包支援
注意:這裡用的是spring-data-redis-1.4.1.RELEASE.jar,這個版本下,Redis版本必須在2.6.2以下,commons-pool2必須在2.0以上,否則會有相容性問題
2、編寫工具類(實現cache介面)
RedisCache.java
package com.redis; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; import org.apache.ibatis.cache.Cache; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.data.redis.connection.jedis.JedisConnection; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer; import org.springframework.data.redis.serializer.RedisSerializer; import com.sun.jndi.url.corbaname.corbanameURLContextFactory; import com.sun.org.apache.xml.internal.serialize.Serializer; import redis.clients.jedis.exceptions.JedisConnectionException; /** * * 使用第三方記憶體資料庫Redis作為二級快取 */ public class RedisCache implements Cache { private static final Logger logger = LoggerFactory.getLogger(RedisCache.class); private static JedisConnectionFactory jedisConnectionFactory; private final String id; /** * The {@code ReadWriteLock}. */ private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(); public RedisCache(final String id) { if (id == null) { throw new IllegalArgumentException("Cache instances require an ID"); } logger.debug("MybatisRedisCache:id=" + id); this.id = id; } @Override public void clear() { JedisConnection connection = null; try { connection = jedisConnectionFactory.getConnection(); // connection.flushDb(); // connection.flushAll(); } catch (JedisConnectionException e) { e.printStackTrace(); } finally { if (connection != null) { connection.close(); } } } @Override public String getId() { return this.id; } @Override public Object getObject(Object key) { Object result = null; JedisConnection connection = null; key = com.util.StringUtil.redisKey(key); try { connection = jedisConnectionFactory.getConnection(); RedisSerializer<Object> serializer = new JdkSerializationRedisSerializer(); result = serializer.deserialize(connection.get(serializer.serialize(key))); } catch (JedisConnectionException e) { e.printStackTrace(); } finally { if (connection != null) { connection.close(); } } return result; } @Override public ReadWriteLock getReadWriteLock() { // TODO Auto-generated method stub return this.readWriteLock; } @Override public int getSize() { int result = 0; JedisConnection connection = null; try { connection = jedisConnectionFactory.getConnection(); result = Integer.valueOf(connection.dbSize().toString()); } catch (JedisConnectionException e) { e.printStackTrace(); } finally { if (connection != null) { connection.close(); } } return result; } @Override public void putObject(Object key, Object value) { JedisConnection connection = null; key = com.util.StringUtil.redisKey(key); try { connection = jedisConnectionFactory.getConnection(); RedisSerializer<Object> serializer = new JdkSerializationRedisSerializer(); connection.set(serializer.serialize(key), serializer.serialize(value)); } catch (JedisConnectionException e) { e.printStackTrace(); } finally { if (connection != null) { connection.close(); } } } @Override public Object removeObject(Object key) { JedisConnection connection = null; Object result = null; try { connection = jedisConnectionFactory.getConnection(); RedisSerializer<Object> serializer = new JdkSerializationRedisSerializer(); result = connection.expire(serializer.serialize(key), 0); } catch (JedisConnectionException e) { e.printStackTrace(); } finally { if (connection != null) { connection.close(); } } return result; } public static void updataObject(String key,Object value){ JedisConnection connection = null; try { connection = jedisConnectionFactory.getConnection(); RedisSerializer<Object> serializer = new JdkSerializationRedisSerializer(); connection.expire(serializer.serialize(key), 0); if(key.indexOf("UserMapper")>0){ connection.expire(serializer.serialize("UserMapper"), 0); } else if(key.indexOf("ArticleMapper")>0){ connection.expire(serializer.serialize("ArticleMapper"), 0); } else if(key.indexOf("CommentMapper")>0){ connection.expire(serializer.serialize("CommentMapper"), 0); } else if(key.indexOf("MessageMapper")>0){ connection.expire(serializer.serialize("MessageMapper"), 0); } } catch (JedisConnectionException e) { e.printStackTrace(); } finally { if (connection != null) { connection.close(); } } } public static void setJedisConnectionFactory(JedisConnectionFactory jedisConnectionFactory) { RedisCache.jedisConnectionFactory = jedisConnectionFactory; } }
RedisCacheTransfer.java
package com.redis; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; public class RedisCacheTransfer{ @Autowired public void setJedisConnectionFactory(JedisConnectionFactory jedisConnectionFactory) { RedisCache.setJedisConnectionFactory(jedisConnectionFactory); } }
3、開啟mybatis中對快取的支援
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <!-- 自動掃描entity目錄, 省掉Configuration.xml裡的手工配置 --> <property name="mapperLocations" value="classpath:com/mapping/*.xml" /> <!-- 以下為新增支援部分star --> <!-- 開啟快取支援 --> <property name="configurationProperties"> <props> <!-- 開啟關鍵--> <prop key="cacheEnabled">true</prop> <!-- 查詢時,關閉關聯物件即時載入以提高效能 --> <prop key="lazyLoadingEnabled">false</prop> <!-- 設定關聯物件載入的形態,此處為按需載入欄位(載入欄位由SQL指定),不會載入關聯表的所有欄位,以提高效能 --> <prop key="aggressiveLazyLoading">true</prop> <!-- 對於未知的SQL查詢,允許返回不同的結果集以達到通用的效果 --> <prop key="multipleResultSetsEnabled">true</prop> <!-- 允許使用列標籤代替列名 --> <prop key="useColumnLabel">true</prop> <!-- 允許使用自定義的主鍵值(比如由程式生成的UUID 32位編碼作為鍵值),資料表的PK生成策略將被覆蓋 --> <prop key="useGeneratedKeys">true</prop> <!-- 給予被巢狀的resultMap以欄位-屬性的對映支援 --> <prop key="autoMappingBehavior">FULL</prop> <!-- 對於批量更新操作快取SQL以提高效能 --> <prop key="defaultExecutorType">BATCH</prop> <!-- 資料庫超過25000秒仍未響應則超時 --> <prop key="defaultStatementTimeout">25000</prop> </props> </property> <!-- end --> </bean>
4、redis屬性檔案redis.properties
# Redis settings
redis.host=127.0.0.1
redis.port=6379
redis.pass=
redis.maxIdle=300
redis.maxActive=600
redis.maxWait=1000
redis.testOnBorrow=true
5、Redis資料管理
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:config.properties</value>
<!-- 掃描redis屬性檔案 -->
<value>classpath:redis.properties</value>
</list>
</property>
</bean>
<!-- redis資料來源 -->
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxIdle" value="${redis.maxIdle}" />
<property name="maxTotal" value="${redis.maxActive}" />
<property name="maxWaitMillis" value="${redis.maxWait}" />
<property name="testOnBorrow" value="${redis.testOnBorrow}" />
</bean>
<!-- Spring-redis連線池管理工廠 -->
<bean id="jedisConnectionFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
p:host-name="${redis.host}" p:port="${redis.port}" p:password="${redis.pass}"
p:pool-config-ref="poolConfig" />
<!-- 使用中間類解決RedisCache.jedisConnectionFactory的靜態注入,從而使MyBatis實現第三方快取 -->
<bean id="redisCacheTransfer" class="com.redis.RedisCacheTransfer">
<property name="jedisConnectionFactory" ref="jedisConnectionFactory" />
</bean>
6、相關的mapper.xml檔案新增快取工具類
<cache type="com.redis.RedisCache" />
7、實體類實現Serialzable介面
至此,ssm專案整合Redis完成。