Redis實現Mybatis的二級緩衝

來源:互聯網
上載者:User
一、Mybatis的緩衝

通大多數ORM層架構一樣,Mybatis自然也提供了對一級緩衝和二級緩衝的支援。一下是一級緩衝和二級緩衝的作用於和定義。

      1、一級緩衝是SqlSession層級的緩衝。在操作資料庫時需要構造 sqlSession對象,在對象中有一個(記憶體地區)資料結構(HashMap)用於儲存快取資料。不同的sqlSession之間的快取資料地區(HashMap)是互相不影響的。

二級緩衝是mapper層級的緩衝,多個SqlSession去操作同一個Mapper的sql語句,多個SqlSession去操作資料庫得到資料會存在二級快取區域,多個SqlSession可以共用二級緩衝,二級緩衝是跨SqlSession的。 

      2、一級緩衝的範圍是同一個SqlSession,在同一個sqlSession中兩次執行相同的sql語句,第一次執行完畢會將資料庫中查詢的資料寫到緩衝(記憶體),第二次會從緩衝中擷取資料將不再從資料庫查詢,從而提高查詢效率。當一個sqlSession結束後該sqlSession中的一級緩衝也就不存在了。Mybatis預設開啟一級緩衝。

      二級緩衝是多個SqlSession共用的,其範圍是mapper的同一個namespace,不同的sqlSession兩次執行相同namespace下的sql語句且向sql中傳遞參數也相同即最終執行相同的sql語句,第一次執行完畢會將資料庫中查詢的資料寫到緩衝(記憶體),第二次會從緩衝中擷取資料將不再從資料庫查詢,從而提高查詢效率。Mybatis預設沒有開啟二級緩衝需要在setting全域參數中配置開啟二級緩衝。

      一般的我們將Mybatis和Spring整合時,mybatis-spring包會自動分裝sqlSession,而Spring通過動態代理sqlSessionProxy使用一個模板方法封裝了select()等操作,每一次select()查詢都會自動先執行openSession(),執行完close()以後調用close()方法,相當於產生了一個新的session執行個體,所以我們無需手動的去關閉這個session(),當然也無法使用mybatis的一級緩衝,也就是說mybatis的一級緩衝在spring中是沒有作用的。

      因此我們一般在項目中實現Mybatis的二級緩衝,雖然Mybatis內建二級緩衝功能,但是如果實在叢集環境下,使用內建的二級緩衝只是針對單個的節點,所以我們採用分布式的二級緩衝功能。一般的緩衝NoSql資料庫如redis,Mancache等,或者EhCache都可以實現,從而更好地服務tomcat叢集中ORM的查詢。


二、Mybatis的二級緩衝的實現

下面主要通過Redis實現Mybatis的二級緩衝功能。 1、設定檔中開啟二級緩衝

  <setting name="cacheEnabled" value="true"/>

   預設二級緩衝是開啟的。 2、實現Mybatis的Cache介面

     Mybatis提供了第三方Cache實現的介面,我們自訂MybatisRedisCache實現Cache介面,代碼如下:

/** * 建立時間:2016年1月7日 上午11:40:00 *  * Mybatis二級緩衝實作類別 *  * @author andy * @version 2.2 */public class MybatisRedisCache implements Cache {private static final Logger LOG = Logger.getLogger(MybatisRedisCache.class); private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(true);private RedisTemplate<Serializable, Serializable> redisTemplate =  (RedisTemplate<Serializable, Serializable>) SpringContextHolder.getBean("redisTemplate"); private String id;private JdkSerializationRedisSerializer jdkSerializer = new JdkSerializationRedisSerializer();public MybatisRedisCache(final String id){if(id == null){throw new IllegalArgumentException("Cache instances require an ID");}LOG.info("Redis Cache id " + id);this.id = id;}@Overridepublic String getId() {return this.id;}@Overridepublic void putObject(Object key, Object value) {if(value != null){redisTemplate.opsForValue().set(key.toString(), jdkSerializer.serialize(value), 2, TimeUnit.DAYS);}}@Overridepublic Object getObject(Object key) {try {if(key != null){Object obj = redisTemplate.opsForValue().get(key.toString());return jdkSerializer.deserialize((byte[])obj); }} catch (Exception e) {LOG.error("redis ");}return null;}@Overridepublic Object removeObject(Object key) {try {if(key != null){redisTemplate.expire(key.toString(), 1, TimeUnit.SECONDS);}} catch (Exception e) {}return null;}@Overridepublic void clear() {//jedis nonsupport}@Overridepublic int getSize() {Long size = redisTemplate.getMasterRedisTemplate().execute(new RedisCallback<Long>(){@Overridepublic Long doInRedis(RedisConnection connection)throws DataAccessException {return connection.dbSize();}});return size.intValue();}@Overridepublic ReadWriteLock getReadWriteLock() {return this.readWriteLock;}}
3、二級緩衝的實用

我們需要將所有的實體類進行序列化,然後在Mapper中添加自訂cache功能。

      

   <cache type="org.andy.shop.cache.MybatisRedisCache"eviction="LRU"flushInterval="6000000"size="1024"readOnly="false"/>

4、Redis中的儲存

     redis會自動的將Sql+條件+Hash等當做key值,而將查詢結果作為value,只有請求中的所有參數都符合,那麼就會使用redis中的二級緩衝。其查詢結果如下:

    




聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.