欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot整合MP通過Redis實現(xiàn)二級緩存方式

 更新時間:2024年01月12日 16:01:53   作者:龍域、白澤  
這篇文章主要介紹了SpringBoot整合MP通過Redis實現(xiàn)二級緩存方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

一級緩存與二級緩存

  • 一級緩存是SqlSession級別的緩存。在操作數(shù)據(jù)庫時需要構(gòu)造sqlSession對象,在對象中有一個數(shù)據(jù)結(jié)構(gòu)(HashMap)用于存儲緩存數(shù)據(jù)。不同的sqlSession之間的緩存數(shù)據(jù)區(qū)域(HashMap)是互相不影響的。 一級緩存是默認開啟的
  • 二級緩存是namespace級別的緩存,多個SqlSession去操作同一個Mapper的sql語句,多個SqlSession可以共用二級緩存,二級緩存是跨SqlSession的

因為在Spring與Mybatis整合后,Mybatis的一級緩存是不能使用的,所以我們一般實現(xiàn)Mybatis的二級緩存,而在集群環(huán)境下,Mybatis的二級緩存只能實現(xiàn)單個節(jié)點的緩存,所以我們采用分布式的二級緩存,這里使用的是Redis的實現(xiàn)

配置文件

spring:
  redis:
    host: 127.0.0.1
    port: 6379
    database: 0
  #配置redis
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource
    username: root
    password: root
    url: jdbc:mysql://localhost:3306/db?useUnicode=true&characterEncoding=UTF-8
#配置Mybatis-Plus
mybatis-plus:
  mapper-locations: classpath:mybatis/mapper/*.xml
  configuration:
    cache-enabled: true

在啟動類上添加@EnableCaching注解

EnableCaching:啟動緩存功能

開啟緩存功能,配置類中需要加上這個注解,有了這個注解以后,spring才知道你需要使用緩存的功能,其他的和緩存相關(guān)的注解才會有效,spring中主要是通過aop實現(xiàn)的,通過aop來攔截需要使用緩存的方法,實現(xiàn)緩存的功能

設(shè)置RedisTemplate

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
 
@Configuration
public class RedisConfiguration {
 
    /**
    * 設(shè)置redisTemplate
    */
    @Bean(name = "redisTemplate")
    public RedisTemplate<Object, Object> redisTemplate(LettuceConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }
}

創(chuàng)建MybatisRedisCache類重寫Mybatis二級緩存的Cache接口的實現(xiàn)

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 javax.annotation.Resource;
import java.util.Set;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
 
/**
 *
 * 使用redis實現(xiàn)Mybatis Plus二級緩存
 *
 */
@Slf4j
public class MybatisRedisCache implements Cache {
 
 
    // 讀寫鎖
    private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(true);
 
    private RedisTemplate redisTemplate;
 
    private RedisTemplate getRedisTemplate(){
        //通過ApplicationContextHolder工具類獲取RedisTemplate
        if (redisTemplate == null) {
            redisTemplate = (RedisTemplate) ApplicationContextHolder.getBeanByName("redisTemplate");
        }
        return redisTemplate;
    }
 
    private final String id;
 
    public MybatisRedisCache(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) {
        //使用redis的Hash類型進行存儲
        getRedisTemplate().opsForHash().put(id,key.toString(),value);
    }
 
    @Override
    public Object getObject(Object key) {
        try {
            //根據(jù)key從redis中獲取數(shù)據(jù)
            return getRedisTemplate().opsForHash().get(id,key.toString());
        } catch (Exception e) {
            e.printStackTrace();
            log.error("緩存出錯 ");
        }
        return null;
    }
 
    @Override
    public Object removeObject(Object key) {
        if (key != null) {
            getRedisTemplate().delete(key.toString());
        }
        return null;
    }
 
    @Override
    public void clear() {
        log.debug("清空緩存");
        Set<String> keys = getRedisTemplate().keys("*:" + this.id + "*");
        if (!CollectionUtils.isEmpty(keys)) {
            getRedisTemplate().delete(keys);
        }
    }
 
    @Override
    public int getSize() {
        Long size = (Long) getRedisTemplate().execute((RedisCallback<Long>) RedisServerCommands::dbSize);
        return size.intValue();
    }
 
    @Override
    public ReadWriteLock getReadWriteLock() {
        return this.readWriteLock;
    }
}

因為RedisTemplate的實例化需要使用Spring的工廠進行創(chuàng)建,而我們創(chuàng)建的MybatisRedisCache類實現(xiàn)的是Mybatis的Cache接口,所以這個類不是由工廠進行管理的,所以我們不能直接在該類中直接使用注解注入RedisTemplate,所以我們創(chuàng)建一個獲取Spring Boot創(chuàng)建好的工廠的ApplicationContextHolder工具類,用于獲取RedisTemplate

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
 
@Component
public class ApplicationContextHolder implements ApplicationContextAware {
    private static ApplicationContext applicationContext;
 
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        ApplicationContextHolder.applicationContext = applicationContext;
    }
 
    //根據(jù)bean name 獲取實例
    public static Object getBeanByName(String beanName) {
        if (beanName == null || applicationContext == null) {
            return null;
        }
        return applicationContext.getBean(beanName);
    }
    //只適合一個class只被定義一次的bean(也就是說,根據(jù)class不能匹配出多個該class的實例)
    public static Object getBeanByType(Class clazz) {
        if (clazz == null || applicationContext == null) {
            return null;
        }
        return applicationContext.getBean(clazz);
    }
    public static String[] getBeanDefinitionNames() {
        return applicationContext.getBeanDefinitionNames();
    }
}

實現(xiàn)ApplicationContextAware接口后,在Spring Boot啟動創(chuàng)建工廠后,就會自動調(diào)用這個接口的setApplicationContext方法,將創(chuàng)建的工廠以參數(shù)的形式傳遞給這個類,在這個方法中我們就可以把工廠給保存下來。

最后我們只需要在Mapper接口上添加@CacheNamespace注解,就完成了

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.chenyx.config.MybatisRedisCache;
import com.chenyx.entity.WeChatUser;
import org.apache.ibatis.annotations.CacheNamespace;
 
 
@CacheNamespace(implementation= MybatisRedisCache.class,eviction=MybatisRedisCache.class)
public interface WeChatUserListMapper extends BaseMapper<WeChatUser>{
}

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java詳解聊天窗口的創(chuàng)建流程

    Java詳解聊天窗口的創(chuàng)建流程

    這篇文章主要介紹了怎么用Java來創(chuàng)建一個聊天窗口,聊天軟件我們經(jīng)常要用,但是你有想過自己怎么去實現(xiàn)它嗎,感興趣的朋友跟隨文章往下看看吧
    2022-04-04
  • java根據(jù)不同的參數(shù)調(diào)用不同的實現(xiàn)類操作

    java根據(jù)不同的參數(shù)調(diào)用不同的實現(xiàn)類操作

    這篇文章主要介紹了java根據(jù)不同的參數(shù)調(diào)用不同的實現(xiàn)類操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • springcloud安裝rabbitmq并配置延遲隊列插件的過程詳解

    springcloud安裝rabbitmq并配置延遲隊列插件的過程詳解

    本期主要講解如何利用docker快速安裝rabbitmq并且配置延遲隊列插件,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-05-05
  • Java實現(xiàn)銀行存取款

    Java實現(xiàn)銀行存取款

    這篇文章主要為大家詳細介紹了Java實現(xiàn)銀行存取款,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-12-12
  • SpringBoot的@RestControllerAdvice作用詳解

    SpringBoot的@RestControllerAdvice作用詳解

    這篇文章主要介紹了SpringBoot的@RestControllerAdvice作用詳解,@RestContrllerAdvice是一種組合注解,由@ControllerAdvice,@ResponseBody組成,本質(zhì)上就是@Component,需要的朋友可以參考下
    2024-01-01
  • Spring之從橋接方法到JVM方法調(diào)用解讀

    Spring之從橋接方法到JVM方法調(diào)用解讀

    這篇文章主要介紹了Spring之從橋接方法到JVM方法調(diào)用解讀,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • Springboot打包為Docker鏡像并部署的實現(xiàn)

    Springboot打包為Docker鏡像并部署的實現(xiàn)

    這篇文章主要介紹了Springboot打包為Docker鏡像并部署的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • 分享15款Java程序員必備的開發(fā)工具

    分享15款Java程序員必備的開發(fā)工具

    這篇文章主要介紹了分享15款Java程序員必備的開發(fā)工具,需要的朋友可以參考下
    2015-02-02
  • SpringBoot接口正確接收時間參數(shù)的幾種方式

    SpringBoot接口正確接收時間參數(shù)的幾種方式

    這篇文章主要給大家介紹了關(guān)于SpringBoot接口正確接收時間參數(shù)的相關(guān)資料,文中通過代碼示例介紹的非常詳細,對大家學(xué)習(xí)或者使用springboot具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-09-09
  • Java比較兩個List的值是否相等的方法

    Java比較兩個List的值是否相等的方法

    這篇文章主要介紹了Java比較兩個List的值是否相等的方法,涉及java針對隊列比較的相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-07-07

最新評論