日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

springboot-mybatisplus-redis二级缓存

發布時間:2024/1/18 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 springboot-mybatisplus-redis二级缓存 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

mybatis可以自己帶有二級緩存的實現,這里加上redis是想把東西緩存到redis中,而不是mybaits自帶的map中。這也就構成了我們看到的springboot + mybatisplus +redis實現二級緩存的題目。

具體步驟如下:

首先加入需要的依賴

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId> </dependency> <dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId> </dependency>

第二步:在application.properties或者yml中配置redis屬性和設置開啟二級緩存(默認是關閉的)

spring.cache.type=redis spring.redis.host=192.168.9.82 spring.redis.jedis.pool.max-active=10 spring.redis.jedis.pool.max-idle=10 spring.redis.jedis.pool.max-wait=3000 spring.redis.jedis.pool.min-idle=20 spring.redis.port=6379 spring.redis.timeout=3000mybatis-plus.configuration.cache-enabled=true #開啟二級緩存

第三步:編寫redis緩存的配置類,大體需要如下三個類,先截圖在上代碼

?ApplicationContextHolder.java類主要用于在另外另個類中可以通過context獲取spring容器中注入的redisTemplate來操作redis。代碼如下:

import org.springframework.context.ApplicationContext;//@Component public class ApplicationContextHolder {private static ApplicationContext applicationContext = null;public static void setApplicationContext(ApplicationContext applicationContext) {ApplicationContextHolder.applicationContext = applicationContext;}public static ApplicationContext getApplicationContext() {return applicationContext;}public static <T> T getBean(String name) {return (T)applicationContext.getBean(name);}public static <T> T getBean(Class clz) {return (T)applicationContext.getBean(clz);}}

MybatisRedisCache.java類實現了Mybatis的Cache接口,這樣才能在執行數據庫操作前調用緩存。代碼如下:

import org.apache.ibatis.cache.Cache; import org.springframework.data.redis.core.RedisCallback; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.ValueOperations;import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock;public class MybatisRedisCache implements Cache {private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();private final String id; // cache instance idprivate RedisTemplate redisTemplate;private static final long EXPIRE_TIME_IN_MINUTES = 30; // redis過期時間public MybatisRedisCache(String id) {if (id == null) {throw new IllegalArgumentException("Cache instances require an ID");}this.id = id;}@Overridepublic String getId() {return id;}/*** Put query result to redis** @param key* @param value*/@Override@SuppressWarnings("unchecked")public void putObject(Object key, Object value) {try {RedisTemplate redisTemplate = getRedisTemplate();ValueOperations opsForValue = redisTemplate.opsForValue();opsForValue.set(key, value, EXPIRE_TIME_IN_MINUTES, TimeUnit.MINUTES);}catch (Throwable t) {t.printStackTrace();}}/*** Get cached query result from redis** @param key* @return*/@Overridepublic Object getObject(Object key) {try {RedisTemplate redisTemplate = getRedisTemplate();ValueOperations opsForValue = redisTemplate.opsForValue();return opsForValue.get(key);}catch (Throwable t) {return null;}}/*** Remove cached query result from redis** @param key* @return*/@Override@SuppressWarnings("unchecked")public Object removeObject(Object key) {try {RedisTemplate redisTemplate = getRedisTemplate();redisTemplate.delete(key);}catch (Throwable t) {t.getMessage();}return null;}/*** Clears this cache instance*/@Overridepublic void clear() {RedisTemplate redisTemplate = getRedisTemplate();redisTemplate.execute((RedisCallback) connection -> {connection.flushDb();return null;});}/*** This method is not used** @return*/@Overridepublic int getSize() {return 0;}@Overridepublic ReadWriteLock getReadWriteLock() {return readWriteLock;}private RedisTemplate getRedisTemplate() {if (redisTemplate == null) {// 這里用到了ApplicationContextHolder.javaredisTemplate = ApplicationContextHolder.getBean("redisTemplate");}return redisTemplate;} } RedisCacheConfig.java類主要用來配置redis的一些屬性,里面這里主要配置了reids序列化。代碼如下: import org.springframework.beans.factory.annotation.Value; import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.CachingConfigurerSupport; import org.springframework.cache.interceptor.CacheErrorHandler; import org.springframework.cache.interceptor.CacheResolver; import org.springframework.cache.interceptor.SimpleCacheErrorHandler; import org.springframework.cache.interceptor.SimpleCacheResolver; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.cache.RedisCacheConfiguration; import org.springframework.data.redis.cache.RedisCacheManager; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.RedisStandaloneConfiguration; import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.RedisSerializationContext; import org.springframework.data.redis.serializer.StringRedisSerializer;import java.time.Duration; import java.util.HashMap; import java.util.Map;/*** ignit改redis緩存* @author lhb* @since 2022/11/24*/ @Configuration public class RedisCacheConfig extends CachingConfigurerSupport {@Value("${spring.redis.host}")private String redisHost;@Value("${spring.redis.port}")private int redisPort;@Beanpublic RedisTemplate<Object, Object> redisTemplate() {RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();redisTemplate.setConnectionFactory(redisConnectionFactory());GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();redisTemplate.setKeySerializer(genericJackson2JsonRedisSerializer);redisTemplate.setValueSerializer(genericJackson2JsonRedisSerializer);redisTemplate.setHashKeySerializer(new StringRedisSerializer());redisTemplate.setHashValueSerializer(genericJackson2JsonRedisSerializer);return redisTemplate;}@Overridepublic CacheResolver cacheResolver() {return new SimpleCacheResolver(cacheManager());}@Overridepublic CacheErrorHandler errorHandler() {return new SimpleCacheErrorHandler();}@Overridepublic CacheManager cacheManager() {Map<String, RedisCacheConfiguration> cacheConfigurationMap = generateCacheConfigMap();RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig().disableCachingNullValues().serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));return RedisCacheManager.builder(redisConnectionFactory()).cacheDefaults(redisCacheConfiguration).withInitialCacheConfigurations(cacheConfigurationMap).build();}public Map<String, RedisCacheConfiguration> generateCacheConfigMap() {Map<String, RedisCacheConfiguration> initialCacheConfiguration = new HashMap<>();initialCacheConfiguration.put("hourCache", RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofHours(1)));//1小時initialCacheConfiguration.put("minCache", RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(1)));initialCacheConfiguration.put("dayCache", RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofDays(1)));return initialCacheConfiguration;}public RedisConnectionFactory redisConnectionFactory() {RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration();configuration.setHostName(redisHost);configuration.setPort(redisPort);configuration.setDatabase(0);LettuceConnectionFactory factory = new LettuceConnectionFactory(configuration);factory.afterPropertiesSet();return factory;}}

第四步:在mapper.xml中添加cache標簽,來告訴mybtisplus這個mapper中的內容使用二級緩存,這個cache標簽放在mapper表中的什么位置都行

<mapper namespace="hisense.HiDevMng.code.hidevConfigManager.web.dao.DevBusRouterelViewDao"><!-- 開啟基于redis的二級緩存 --><cache type="hisense.HiDevMng.code.base.config.cache.MybatisRedisCache"/><select id="getOrgList" resultType="his.api.dto.OrgDto">SELECT * from table1 WHERE br.BUSID IN<foreach collection="ids" index="index" item="item" open="(" separator="," close=")">#{item}</foreach></select> </mapper>

第五步:在啟動類中實現ApplicationContextAware接口,目的是拿到spring容器的context,然后給ApplicationContextHolder,這樣我們的redis緩存的配置類中就可以通過applicationContext來得到容器中中的redisTemplate進行redis操作了。添加如下代碼:

public class StartApplication extends SpringBootServletInitializer implements ApplicationContextAware {public static void main(String[] args) {SpringApplication.run(StartApplication.class, args);}@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {//重點在此,通過這個賦值contextApplicationContextHolder.setApplicationContext(applicationContext);} }

網上很多帖子給出的方式是自己單獨寫一個類來實現ApplicationContextAware接口,但是因為我的項目中用到了@PostConstruct注解,那樣會導致ApplicationContrext為空,所以我選擇了通過上面在啟動類給ApplicationContextHolder賦值的方式。

第六步,測試,創建測試類例如

RunWith(SpringRunner.class) @SpringBootTest(classes = StartApplication.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) public class test {@Autowiredprivate MyDao dao;@Testpublic void testOne() {Set<String> ids = new HashSet<>();ids.add("25191027172915794000");List<BusOrgDto> busOrgList = dao.getBusOrgList(ids);System.out.println(busOrgList.size());System.out.println("====================================================");List<BusOrgDto> busOrgList1 = dao.getBusOrgList(ids);System.out.println(busOrgList1.size());}}

?運行2次查詢,但是只出現一次如下圖的log,就說明第二次執行使用redis緩存中的數據了

?出現一次Preparing:就說明執行的是數據庫查詢,沒走redis緩存。當我們多次執行都不在顯示這個Preparing:了就說明緩存成功了。

總結:

這里就不把代碼放git上了,直接從上面把代碼都拷貝下來,就可以執行了。關于什么是二級緩存網上可以自行百度。

代碼中還存在完善的空間,比如多久后自動從緩存刪除等,大家可以自行了解下。這里只是為了給初學者使用,寫多了怕容易亂。謝謝支持

總結

以上是生活随笔為你收集整理的springboot-mybatisplus-redis二级缓存的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。