redis的安裝 http://liuyieyer.iteye.com/blog/2078093redis
redis的主從高可用 http://liuyieyer.iteye.com/blog/2078095數據庫
Mybatis 的使用很少說。apache
Mybatis爲了方便咱們擴展緩存定義了一個Cache接口,看看ehcache-mybatis的源碼就明白了。咱們要使用本身的cache一樣的實現Cache接口便可。直接上代碼緩存
public class RedisCache implements Cache { private static Log logger = LogFactory.getLog(RedisCache.class); private Jedis redisClient = createClient(); /** The ReadWriteLock. */ 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(">>>>>>>>>>>>>>>>>>>>>>>>MybatisRedisCache:id=" + id); this.id = id; } @Override public String getId() { return this.id; } @Override public int getSize() { return Integer.valueOf(redisClient.dbSize().toString()); } @Override public void putObject(Object key, Object value) { logger.debug(">>>>>>>>>>>>>>>>>>>>>>>>putObject:" + key + "=" + value); redisClient.set(SerializeUtil.serialize(key.toString()), SerializeUtil.serialize(value)); } @Override public Object getObject(Object key) { Object value = SerializeUtil.unserialize(redisClient.get(SerializeUtil.serialize(key.toString()))); logger.debug(">>>>>>>>>>>>>>>>>>>>>>>>getObject:" + key + "=" + value); return value; } @Override public Object removeObject(Object key) { return redisClient.expire(SerializeUtil.serialize(key.toString()), 0); } @Override public void clear() { redisClient.flushDB(); } @Override public ReadWriteLock getReadWriteLock() { return readWriteLock; } protected static Jedis createClient() { try { JedisPool pool = new JedisPool(new JedisPoolConfig(), "172.60.0.172"); return pool.getResource(); } catch (Exception e) { e.printStackTrace(); } throw new RuntimeException("初始化鏈接池錯誤"); } } 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) { if(bytes == null)return null; ByteArrayInputStream bais = null; try { // 反序列化 bais = new ByteArrayInputStream(bytes); ObjectInputStream ois = new ObjectInputStream(bais); return ois.readObject(); } catch (Exception e) { e.printStackTrace(); } return null; } }
在看ehcache-mybatis的源碼 它真正使用cache的方式是經過集成org.apache.ibatis.cache.decorators.LoggingCache 這個類實現的,照貓畫虎,直接咱們也繼承mybatis
public class LoggingRedisCache extends LoggingCache { public LoggingRedisCache(String id) { super(new RedisCache(id)); } }
在mapper.xml中添加以下cache標籤app
<!-- 啓用緩存 --> <cache type="cn.seafood.cache.LoggingRedisCache" />
在mybatis的核心文件中開啓緩存ide
<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" /> <!-- <setting name="enhancementEnabled" value="true"/> --> <!-- 設置超時時間,它決定驅動等待一個數據庫響應的時間。 --> <setting name="defaultStatementTimeout" value="25000" /> </settings>
<setting name="lazyLoadingEnabled" value="false" />ui
<setting name="aggressiveLazyLoading" value="true" />this
注意着兩個屬性,須要把屬性延遲加載和關聯對象加載給關閉了,否則放進redis中的cglib代理對象,在對數據發生更改的時候,會出錯。debug