SpringMVC+Mybatis+MySQL配置Redis緩存
1.准備環境:
SpringMVC:spring-framework-4.3.5.RELEASE-dist
Mybatis:3.4.2
MySQL:5.0
JDK:1.8
IDE:Eclipse4.6.1
以及配置好的SpringMVC+Mybatis項目
2.需要添加的jar包
jedis-2.9.0.jar
或者使用POM配置
<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
3.配置
配置分為以下幾個部分:
1、Java使用Jedis實現Mybatis的Cache接口,RedisCache.java
package redisCache;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.apache.ibatis.cache.Cache;
import org.apache.log4j.Logger;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import tool.SerializeUtil;
public class RedisCache implements Cache {
private static Logger logger = Logger.getLogger(RedisCache.class);
/* 創建訪問Redis數據庫的Redis客戶端 */
private Jedis redisClient = createReids();
/* 讀寫鎖 */
private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
private String id;
public RedisCache(final String id) {
if (id == null) {
throw new IllegalArgumentException("Cache instances require an ID");
}
logger.debug(">>>>>>>>>>>>>>>>>>>>>>>>RedisCache:id=" + id);
this.id = id;
}
@Override
public void clear() {
redisClient.flushDB();
}
@Override
public String getId() {
return this.id;
}
@Override
public Object getObject(Object key) {
Object value = SerializeUtil.unserialize(redisClient.get(SerializeUtil.serialize(key.toString())));
logger.debug(">>>>>>>>>>>>>>>>>>>>>>>>getObject:" + key + " value=" + value);
return value;
}
@Override
public ReadWriteLock getReadWriteLock() {
return readWriteLock;
}
@Override
public int getSize() {
return Integer.valueOf(redisClient.dbSize().toString());
}
@Override
public void putObject(Object key, Object value) {
logger.debug(">>>>>>>>>>>>>>>>>>>>>>>>putObject:" + key + " value=" + value);
redisClient.set(SerializeUtil.serialize(key.toString()), SerializeUtil.serialize(value));
}
@Override
public Object removeObject(Object key) {
return redisClient.expire(SerializeUtil.serialize(key.toString()), 0);
}
protected static Jedis createReids() {
JedisPool pool = new JedisPool(new JedisPoolConfig(), "127.0.0.1");
Jedis result = pool.getResource();
return result;
}
}
RedisCache文件結構如下
Tool包下的序列化工具SerializeUtil.java
package tool;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class SerializeUtil {
public static byte[] serialize(Object object) {
ObjectOutputStream oos = null;
ByteArrayOutputStream baos = null;
try {
// 序列化
baos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(baos);
oos.writeObject(object);
byte[] bytes = baos.toByteArray();
return bytes;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static Object unserialize(byte[] bytes) {
ByteArrayInputStream bais = null;
try {
// 反序列化
bais = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bais);
return ois.readObject();
} catch (Exception e) {
}
return null;
}
}
2、配置Mybatis開啟緩存
配置SqlMapConfig.xml添加一下屬性
<configuration>
...
<settings>
...
<!-- 這個配置使全局的映射器啟用或禁用緩存 -->
<setting name="cacheEnabled" value="true" />
<!-- 對於未知的SQL查詢,允許返回不同的結果集以達到通用的效果 -->
<setting name="multipleResultSetsEnabled" value="true" />
<!-- 配置默認的執行器。SIMPLE 執行器沒有什么特別之處。REUSE 執行器重用預處理語句。BATCH 執行器重用語句和批量更新 -->
<setting name="defaultExecutorType" value="REUSE" />
<!-- 全局啟用或禁用延遲加載。當禁用時,所有關聯對象都會即時加載。 -->
<setting name="lazyLoadingEnabled" value="false" />
<setting name="aggressiveLazyLoading" value="true" />
<!-- 全局性地啟用或禁用運行時字節碼增強,以優化訪問Java Bean屬性的性能,同時優化延遲加載的性能。 -->
<!-- <setting name="enhancementEnabled" value="true"/> -->
<!-- 設置超時時間,它決定驅動等待一個數據庫響應的時間。 -->
<setting name="defaultStatementTimeout" value="25000" />
...
</settings>
...
</configuration>
3、在Mapper.xml中使用緩存
舉例,如我使用的TbUserMapperCustom.xml,在其中添加使用緩存
<mapper namespace="mapper.TbUserMapperCustom">
...
<!-- 淘汰模式為LRU,使用RedisCache來實現緩存 -->
<cache eviction="LRU" type="redisCache.RedisCache" />
...
</mapper>
4、使用效果
4、注意事項
1、在緩存的過程中,需要把對象序列化轉化為字節數組存入,那么需要緩存的Bean類就需要實現Serializable接口。
2、由於我為了Bean類的擴展性沒有直接使用Mybatis逆向工程生成的原始類,而是繼承了原TbUser,使用TbUserCustom,如果僅僅是TbUserCustom實現了Serializable接口而父類沒有實現Serializable接口的話,在序列化、反序列化的過程中將無法對數據進行正確的讀寫,讀出來的對象將為空,所以如果要傳輸的數據有父類的話,那么父類也需要實現Serializable接口。
3、在使用前你肯定需要打開Redis服務