1. 程式人生 > >mybatis plus使用redis作為二級快取

mybatis plus使用redis作為二級快取

建議快取放到 service 層,你可以自定義自己的 BaseServiceImpl 重寫註解父類方法,繼承自己的實現。為了方便,這裡我們將快取放到mapper層。mybatis-plus整合redis作為二級快取與mybatis整合redis略有不同。

1. mybatis-plus開啟二級快取

mybatis-plus.configuration.cache-enabled=true

2. 定義RedisTemplate的bean交給spring管理,這裡為了能將物件直接存取到redis中,進行了一些序列化的操作

@Bean(value = "redisTemplate")
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(connectionFactory);
        //Use Jackson 2Json RedisSerializer to serialize and deserialize the value of redis (default JDK serialization)
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        //將類名稱序列化到json串中
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        //設定輸入時忽略JSON字串中存在而Java物件實際沒有的屬性
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);

        //Use String RedisSerializer to serialize and deserialize the key value of redis
        RedisSerializer redisSerializer = new StringRedisSerializer();
        //key
        redisTemplate.setKeySerializer(redisSerializer);
        redisTemplate.setHashKeySerializer(redisSerializer);
        //value
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);

        redisTemplate.afterPropertiesSet();
        return redisTemplate;

    }

3. 自定義自己的快取管理

package com.qctchina.headsetserver.config;

import com.qctchina.headsetserver.util.SpringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.cache.Cache;
import org.springframework.data.redis.connection.RedisServerCommands;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.CollectionUtils;

import java.util.Set;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * @author shuangyueliao
 * @create 2019/9/10 14:02
 * @Version 0.1
 */
@Slf4j
public class MybatisRedisCache implements Cache {


    // 讀寫鎖
    private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(true);

    //這裡使用了redis快取,使用springboot自動注入
    private RedisTemplate<String, Object> redisTemplate;

    private String id;

    public MybatisRedisCache(final String id) {
        if (id == null) {
            throw new IllegalArgumentException("Cache instances require an ID");
        }
        this.id = id;
    }

    @Override
    public String getId() {
        return this.id;
    }

    @Override
    public void putObject(Object key, Object value) {
        if (redisTemplate == null) {
            //由於啟動期間注入失敗,只能執行期間注入,這段程式碼可以刪除
            redisTemplate = (RedisTemplate<String, Object>) SpringUtil.getBean("redisTemplate");
        }
        if (value != null) {
            redisTemplate.opsForValue().set(key.toString(), value);
        }
    }

    @Override
    public Object getObject(Object key) {
        if (redisTemplate == null) {
            //由於啟動期間注入失敗,只能執行期間注入,這段程式碼可以刪除
            redisTemplate = (RedisTemplate<String, Object>) SpringUtil.getBean("redisTemplate");
        }
        try {
            if (key != null) {
                return redisTemplate.opsForValue().get(key.toString());
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("快取出錯 ");
        }
        return null;
    }

    @Override
    public Object removeObject(Object key) {
        if (redisTemplate == null) {
            //由於啟動期間注入失敗,只能執行期間注入,這段程式碼可以刪除
            redisTemplate = (RedisTemplate<String, Object>) SpringUtil.getBean("redisTemplate");
        }
        if (key != null) {
            redisTemplate.delete(key.toString());
        }
        return null;
    }

    @Override
    public void clear() {
        log.debug("清空快取");
        if (redisTemplate == null) {
            redisTemplate = (RedisTemplate<String, Object>) SpringUtil.getBean("redisTemplate");
        }
        Set<String> keys = redisTemplate.keys("*:" + this.id + "*");
        if (!CollectionUtils.isEmpty(keys)) {
            redisTemplate.delete(keys);
        }
    }

    @Override
    public int getSize() {
        if (redisTemplate == null) {
            //由於啟動期間注入失敗,只能執行期間注入,這段程式碼可以刪除
            redisTemplate = (RedisTemplate<String, Object>) SpringUtil.getBean("redisTemplate");
        }
        Long size = redisTemplate.execute((RedisCallback<Long>) RedisServerCommands::dbSize);
        return size.intValue();
    }

    @Override
    public ReadWriteLock getReadWriteLock() {
        return this.readWriteLock;
    }
}

SpringUtil是手動獲取bean的工具類

@Component
public class SpringUtil implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        SpringUtil.applicationContext = applicationContext;
    }

    public static Object getBean(String name){
        return applicationContext.getBean(name);
    }

    public static <T> T getBean(String name, Class<T> clazz){
        return applicationContext.getBean(name, clazz);
    }

    public static <T> T getBean(Class<T> clazz){
        return applicationContext.getBean(clazz);
    }
}

4. 在mapper上加上註解@CacheNamespace

@CacheNamespace(implementation= MybatisRedisCache.class,eviction=MybatisRedisCache.class)
public interface CommonMapper extends BaseMapper<Common> {

如果呼叫該mapper下的方法,那麼會使用redis快取

相關推薦

mybatis plus使用redis作為二級快取

建議快取放到 service 層,你可以自定義自己的 BaseServiceImpl 重寫註解父類方法,繼承自己的實現。為了方便,這裡我們將快取放到mapper層。mybatis-plus整合redis作為二級快取與mybatis整合redis略有不同。 1. mybatis-plus開啟二級快取 mybat

MyBatis -- 整合Redis二級快取

一。MyBatis一級二級快取      一級快取:     MyBatis一級快取為SqlSession級別的快取,預設開啟,相同的SqlSession物件查詢相同條件的結果時,如果存在一級快取,那麼只會訪問資料庫一次,一級快取在sqlSession關閉後失效,

mybatis+redis+mybatis-redis實現二級快取

mybatis-redis原始碼: https://github.com/mybatis/redis-cache mybatis-redis官網說明: http://www.mybatis.org/redis-cache/index.html 說明: 1、MyBatis預設開啟二級快取

Hibernate5使用memcached作為二級快取

解決的問題        因為專案要進行升級,原先是使用hibernate3,spring3的,但是需要對專案進行升級重構需要使用spring4。為了方便以後使用spring cloud相關元件,所以對老專案進行依賴的升級,目標就是將專案調整為spring4,hibernat

MyBatis學習8】MyBatis中的二級快取

1. 二級快取的原理   前面介紹了,mybatis中的二級快取是mapper級別的快取,值得注意的是,不同的mapper都有一個二級快取,也就是說,不同的mapper之間的二級快取是互不影響的。為了更加清楚的描述二級快取,先來看一個示意圖:     從圖中可以看出: sqlSession1去查詢使用

Mybatis一級、二級快取

一級快取 首先做一個測試,建立一個mapper配置檔案和mapper介面,我這裡用了最簡單的查詢來演示。 <mapper namespace="cn.elinzhou.mybatisTest.mapper.UserMapper">

myBatis原始碼解析-二級快取的實現方式

1. 前言 前面近一個月去寫自己的mybatis框架了,對mybatis原始碼分析止步不前,此文繼續前面的文章。開始分析mybatis一,二級快取的實現。附上自己的專案github地址:https://github.com/xbcrh/simple-ibatis  對mybatis感興趣的同學可關注

spring+ mybatis 二級快取使用 redis作為快取

springMybatisConfig.xml配置 <?xml version="1.0" encoding="utf-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="ht

redis作為mybatis二級快取

redis作為二級快取伺服器,來替代mybatis的二級快取,至於二級快取有什麼缺點我想大家都懂吧,   [service] 2016-08-31 21:01:32,912 - com.erp.dao.TestMybatisMapper.selectByPrimaryKey -19

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

文件 .class lose linux csdn instance 管理 total lin 轉載:http://blog.csdn.net/xiadi934/article/details/50786293 項目環境: 在SpringMVC +Spring + MyB

mybatis高階(3)_延遲載入_深度延遲_一級快取_二級快取

mybatis高階(3)_延遲載入_深度延遲_一級快取_二級快取 設定延遲載入需要在mybatis.xml中設定 注: 侵入式延遲載入為真時是延遲載入 侵入式延遲載入為假時是深度延遲載入 <!-- 延遲載入和深度延遲載入 --> <settings

MyBatis一級快取二級快取詳解

一級快取   Mybatis對快取提供支援,但是在沒有配置的預設情況下,它只開啟一級快取,一級快取只是相對於同一個SqlSession而言。所以在引數和SQL完全一樣的情況下,我們使用同一個SqlSession物件呼叫一個Mapper方法,往往只執行一次SQL,因為使用SelSession第一次

SpringBoot+Mybatis環境下如何用Redis做Mybatis二級快取

mybatis的一級快取和二級快取? 一級快取是SqlSession級別的快取。在操作資料庫時需要構造 sqlSession物件,在物件中有一個(記憶體區域)資料結構(HashMap)用於儲存快取資料。不同的sqlSession之間的快取資料區域(HashMap)是互相不影響的。  

MyBatis二級快取解析

一、建立Cache的完整過程 我們從SqlSessionFactoryBuilder解析mybatis-config.xml配置檔案開始: Reader reader = Resources.getResourceAsReader("mybatis-config.xml"); SqlSe

mybatis二級快取的使用

1.引入ehcache的jar包和mybatis整合ehcache的jar包; <!-- ehchache --> <dependency> <groupId>net.sf.ehcache</groupI

Mybatis的一級和二級快取

作用域 一級快取:session,當openSession()之後,如果執行相同的sql(相同的語句和引數),Mybatis不執行sql,而是從快取中返回 二級快取:mapper的一個namespace,同一個namespace中查詢sql可以從快取中獲取,二級快取可以跨sessio

mybatis基礎系列(四)——關聯查詢、延遲載入、一級快取二級快取

關本文是Mybatis基礎系列的第四篇文章,點選下面連結可以檢視前面的文章: mybatis基礎系列(三)——動態sql mybatis基礎系列(二)——基礎語法、別名、輸入對映、輸出對映 mybatis基礎系列(一)——mybatis入門 關聯查詢 在進行表設計時,往往需要在具體的業務基礎上分析表與表之間的

mybatis和hibernate的一級、二級快取

MyBatis一級快取: hibernate一級快取: 基本差不多  HashMap本地快取,作用域為session,session級別的快取,通過get,update可以將物件放到一級快取中,當 Session flush 或 close&n

MyBatis 本地快取二級快取使用以及原始碼分析 第一篇

本地快取    也稱為一級快取,分為兩個作用域SESSION和STATEMENT。官網中的描述:MyBatis利用本地快取機制(Local Cache)防止迴圈引用(迴圈引用)和加速重複巢狀查詢。預設值為SESSION,這種情況下會快取一個會話中執行的所有查詢。若設定值為ST

Mybatis的一、二級快取

  MyBatis快取介紹   Mybatis和Hibernate一樣,也有一級和二級快取,同樣預設開啟的只有一級快取,二級快取也需要手動配置開啟。        Mybatis 提供了快取機制減輕資料庫壓力,提高資料庫效能 一