【强迫症患者必备】SpringBoot项目中Mybatis使用mybatis-redis开启三级缓存必须创建redis.properties优化方案

springboot项目中mybatis使用mybatis-redis开启三级缓存需要创建redis.properties优化方案

  • 前言
  • 下载mybatis-redis源码分析
    • RedisCache 代码
    • RedisConfigurationBuilder的parseConfiguration方法
  • 优化改造
    • 1.创建JedisConfig类
    • 2.复制RedisCache代码创建自定义的MyRedisCache
    • 3.指定缓存实现类为自己的类
      • xml方式
      • 注解方式
  • 总结


前言

Springboot项目中mybatis使用mybatis-redis开启三级缓存需要创建redis.properties优化方案,如何开启三级缓存详见 十分钟带你了解Mybatis一、二、三级缓存,赶紧用起来!。
本文主要解决在使用mybatis-redis开启三级缓存时候,必须强制创建redis.properties文件,这样导致redis配置在多个地方存在,强迫症患者是无法忍受的,下面开始我们的优化改造。


下载mybatis-redis源码分析

发现mybatis-redis也是实现Cache接口实现三级缓存

RedisCache 代码

public final class RedisCache implements Cache {

  private final ReadWriteLock readWriteLock = new DummyReadWriteLock();

  private String id;

  private static JedisPool pool;

  public RedisCache(final String id) {
    if (id == null) {
      throw new IllegalArgumentException("Cache instances require an ID");
    }
    this.id = id;
    RedisConfig redisConfig = RedisConfigurationBuilder.getInstance().parseConfiguration();
	pool = new JedisPool(redisConfig, redisConfig.getHost(), redisConfig.getPort(),
			redisConfig.getConnectionTimeout(), redisConfig.getSoTimeout(), redisConfig.getPassword(),
			redisConfig.getDatabase(), redisConfig.getClientName());
  }
  。。。。
  略
}

可以看到底层采用jedis做缓存框架,通过RedisConfigurationBuilder.getInstance().parseConfiguration()去获取redis配置

RedisConfigurationBuilder的parseConfiguration方法

public RedisConfig parseConfiguration(ClassLoader classLoader) {
	Properties config = new Properties();

	InputStream input = classLoader.getResourceAsStream(redisPropertiesFilename);
	if (input != null) {
		try {
			config.load(input);
		} catch (IOException e) {
			throw new RuntimeException(
					"An error occurred while reading classpath property '"
							+ redisPropertiesFilename
							+ "', see nested exceptions", e);
		} finally {
			try {
				input.close();
			} catch (IOException e) {
				// close quietly
			}
		}
	}

	RedisConfig jedisConfig = new RedisConfig();
	setConfigProperties(config, jedisConfig);
	return jedisConfig;
}

可以看到这边读取是redisPropertiesFilename文件
【强迫症患者必备】SpringBoot项目中Mybatis使用mybatis-redis开启三级缓存必须创建redis.properties优化方案_第1张图片
上图可以看到默认是redis.properties文件,也可以通过system参数指定,且RedisConfigurationBuilder类是一个final类,基本上没用方法可以处理。因为源码内部只支持properties文件解析,没兼容springboot配置。

优化改造

1.创建JedisConfig类

代码如下:

package com.uhu.redis.cache;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.time.Duration;

/**
 * @author liujunjie
 * @description
 * @create 2023-11-29 11:54
 **/
@Configuration
@Slf4j
public class JedisConfig {
    @Value("${spring.redis.host}")
    private String host;
    @Value("${spring.redis.port}")
    private int port;
    @Value("${spring.redis.password}")
    private String password;
    @Value("${spring.redis.timeout}")
    private Duration timeout;
    @Value("${spring.redis.jedis.pool.max-active}")
    private int maxActive;
    @Value("${spring.redis.jedis.pool.max-idle}")
    private int maxIdle;
    @Value("${spring.redis.jedis.pool.min-idle}")
    private int minIdle;

    @Bean
    public JedisPool jedisPool() {
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxIdle(maxIdle);
        jedisPoolConfig.setMinIdle(minIdle);
        jedisPoolConfig.setMaxTotal(maxActive);
        // 是否启用pool的jmx管理功能, 默认true
        jedisPoolConfig.setJmxEnabled(true);

        JedisPool jedisPool = new JedisPool(jedisPoolConfig, host, port, Integer.parseInt(String.valueOf(timeout.toMillis())), password);
        log.info("JedisPool连接成功:" + host + ":" + port);
        return jedisPool;
    }
}

2.复制RedisCache代码创建自定义的MyRedisCache

代码如下:

/**
 * Copyright 2015 the original author or authors.
 * 

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *

* http://www.apache.org/licenses/LICENSE-2.0 *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.uhu.cache; import cn.hutool.extra.spring.SpringUtil; import org.apache.ibatis.cache.Cache; import org.mybatis.caches.redis.RedisCallback; import org.mybatis.caches.redis.SerializeUtil; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import java.util.Map; /** * Cache adapter for Redis. * * @author Eduardo Macarron */ public class MyRedisCache implements Cache { private String id; private static JedisPool pool; public MyRedisCache(final String id) { if (id == null) { throw new IllegalArgumentException("Cache instances require an ID"); } this.id = id; pool = SpringUtil.getBean(JedisPool.class); } private Object execute(RedisCallback callback) { Jedis jedis = pool.getResource(); try { return callback.doWithRedis(jedis); } finally { jedis.close(); } } @Override public String getId() { return this.id; } @Override public int getSize() { return (Integer) execute(new RedisCallback() { @Override public Object doWithRedis(Jedis jedis) { Map<byte[], byte[]> result = jedis.hgetAll(id.toString().getBytes()); return result.size(); } }); } @Override public void putObject(final Object key, final Object value) { execute(new RedisCallback() { @Override public Object doWithRedis(Jedis jedis) { jedis.hset(id.toString().getBytes(), key.toString().getBytes(), SerializeUtil.serialize(value)); return null; } }); } @Override public Object getObject(final Object key) { return execute(new RedisCallback() { @Override public Object doWithRedis(Jedis jedis) { return SerializeUtil.unserialize(jedis.hget(id.toString().getBytes(), key.toString().getBytes())); } }); } @Override public Object removeObject(final Object key) { return execute(new RedisCallback() { @Override public Object doWithRedis(Jedis jedis) { return jedis.hdel(id.toString(), key.toString()); } }); } @Override public void clear() { execute(new RedisCallback() { @Override public Object doWithRedis(Jedis jedis) { jedis.del(id.toString()); return null; } }); } @Override public String toString() { return "Redis {" + id + "}"; } }

3.指定缓存实现类为自己的类

xml方式

<mapper namespace="xxx">
     <cache type="com.uhu.redis.cache.MyRedisCache"/>
     
     <select id="findAll" resultType="xxx" useCache="false">
     select>
mapper>

注解方式

@CacheNamespace(implementation = MyRedisCache.class)
@Mapper
public interface XxxDao {
}

总结

以上就是SpringBoot项目中Mybatis使用mybatis-redis开启三级缓存必须创建redis.properties优化方案,通过简单的源码改造,就可以让许多强迫症患者心情舒畅。

你可能感兴趣的:(Java,SpringBoot,缓存,spring,boot,mybatis,redis,mybatis-redis,java)