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

news2024/9/22 7:41:31

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文件
在这里插入图片描述
上图可以看到默认是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.
 * <p>
 * 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
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * 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优化方案,通过简单的源码改造,就可以让许多强迫症患者心情舒畅。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1273122.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

分享超实用的软文撰写步骤!建议收藏

一想到写软文就头大&#xff0c;根本不知道从哪里下手&#xff0c;这是很多写手在创作过程中会遇到的问题。 一篇软文写得好不好&#xff0c;关键就要看你的创作步骤到不到位&#xff0c;软文创作是有一套可执行的具体方式的&#xff0c;跟着步骤来&#xff0c;你也能轻轻松松…

【java扫盲贴】final修饰变量

引用类型&#xff1a;地址不可变 //Java中的引用类型分为类&#xff08;class&#xff09;、接口&#xff08;interface&#xff09;、数组&#xff08;array&#xff09;和枚举&#xff08;enum&#xff09;。//string是特殊的引用类型&#xff0c;他的底层是被final修饰的字…

麒麟操作系统网桥配置

网桥概念&#xff1a; Bridge 是 Linux 上用来做 TCP/IP 二层协议交换的设备&#xff0c;其功能可 以简单的理解为是一个二层交换机或者 Hub&#xff1b;多个网络设备可以连接 到同一个 Bridge&#xff0c;当某个设备收到数据包时&#xff0c;Bridge 会将数据转发 给其他设备。…

osgFX扩展库-刻线特效、立方图镜面高光特效(2)

刻线特效 刻线特效(osgFX::Scribe)是一个双通道的特效&#xff0c;第一个通道以通常的方式渲染图形&#xff0c;第二个通道使用线框模式。用户设置好光照和材质之后&#xff0c;即可使用指定的颜色进行渲染。这个特效使用了PolygonOffset渲染属性类来避免多边形斑驳(Z-fighting…

【C++ Primer Plus学习记录】嵌套循环和二维数组

for循环是一种处理数组的工具。下面进一步讨论如何使用嵌套for循环中来处理二维数组。 C没有提供二维数组类型&#xff0c;但是用户可以创建每个元素本身都是数组的数组。例如&#xff0c;假设要存储5个城市在4年间的最高温度&#xff0c;可以这样声明数组&#xff1a; int m…

机器学习入门(第四天)——朴素贝叶斯

知识树 Knowledge tree P(y|x)&#xff0c;P给定x的条件下&#xff0c;y的概率。如&#xff1a;P(y我招女孩子喜欢的概率|我是学生) 一个小故事 A story 女朋友和妈妈掉河里&#xff0c;路人拿出3颗豆&#xff0c;两颗红豆1颗绿豆。如果我抽中红豆救女朋友&#xff0c;抽中绿…

【用unity实现100个游戏之17】从零开始制作一个类幸存者肉鸽(Roguelike)游戏5(附项目源码)

文章目录 本节最终效果前言能力升级系统绘制升级按钮武器升级道具升级治疗物品效果双手放置武器控制武器移动转向排序默认先隐藏武器&#xff0c;去除默认的武器精灵图片数据联动完善升级界面控制窗口开启关闭时间控制&#xff0c;升级暂停游戏每次升级随机获取属性项目控制等级…

2023/11/24JAVAweb学习(Vue常用指令,Vue.js文件,Ajax,Axios两种请求,Vue-cli脚手架,Vue项目,Element)

age只会执行成立的,show其实都展示了,通过display不展示 使用Vue,必须引入Vue.js文件 假如运行报错,以管理员身份打开vscode,再运行 ------------------------------------------------------------------- 更改端口号

如何有效避免七个常见的身份验证漏洞

引言 随着网络威胁的数量不断增加&#xff0c;了解学习可能会危及到客户在线身份的常见身份验证漏洞就显得格外重要。如果需要在网上满足客户的需求&#xff0c;并使用传统的身份验证机制时&#xff0c;就要对身份验证漏洞保持警惕。 只有了解了这些漏洞&#xff0c;才可以更…

如何配置mybatis中mapper对应关系,解决mybatis报错:Invalid bound statement (not found):

先看一下报错信息&#xff1a; Invalid bound statement&#xff1a;意思是无效的绑定语句 原因就是&#xff1a;在使用mybatis时mapper.xml没有和mapper接口对应起来 解决方式 第一种&#xff1a; 将mapper.xml和mapper接口放在同一位置 在pom中配置&#xff1a; <reso…

C# WPF上位机开发(抽奖程序)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 每到年末或者是尾牙的时候&#xff0c;很多公司都会办一些年终的清楚活动&#xff0c;感谢员工过去一年辛苦的付出。这个时候&#xff0c;作为年会…

专访|OpenTiny 开源社区 常浩:完成比完美更重要

前言 2023年已过大半&#xff0c;备受关注的 OpenTiny*开源之夏活动也顺利结项。开源之夏由中国科学院软件研究所发起的计划&#xff0c;目的在于鼓励在校学生积极参与开源软件的开发维护&#xff0c;推动优秀开源软件社区的繁荣发展。该活动联合各大开源社区&#xff0c;聚焦…

五要素超声波气象站-气象站小百科

随着科技的发展&#xff0c;人们对气象监测的需求也越来越高。为了满足这一需求&#xff0c;一款全新的五要素超声波气象站应运而生。这款气象站不仅具有高精度的测量能力&#xff0c;而且能够实时监测天气变化&#xff0c;为人们提供准确的气象数据。 一、实时监测&#xff0…

【数值计算方法(黄明游)】矩阵特征值与特征向量的计算(三):Jacobi 旋转法【理论到程序】

文章目录 一、Jacobi 旋转法1. 基本思想2. 计算过程演示 二、Python实现迭代过程&#xff08;调试&#xff09; 矩阵的特征值&#xff08;eigenvalue&#xff09;和特征向量&#xff08;eigenvector&#xff09;在很多应用中都具有重要的数学和物理意义。Jacobi 旋转法是一种用…

华为云之云桌面Workspace的使用体验

华为云之云桌面Workspace的使用体验 一、云桌面Workspace介绍1.云桌面简介2.云桌面特点3. 云桌面应用场景①远程移动办公②协同办公③安全办公④公用终端⑤图形制作渲染 二、本次实践介绍1. 本次实践目的2. 本次实践环境 三、购买云桌面1. 进入华为云的云桌面购买界面2. 选择购…

智能优化算法应用:基于生物地理学算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于生物地理学算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于生物地理学算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.生物地理学算法4.实验参数设定5.算法结果…

【蓝桥杯选拔赛真题70】Scratch输入输出数字 少儿编程scratch图形化编程 蓝桥杯创意编程选拔赛真题解析

目录 scratch输入输出数字 一、题目要求 编程实现 二、案例分析 1、角色分析

文件夹重命名技巧:用关键词替换文件夹名称指定内容的右侧文字

在日常生活中&#xff0c;经常要管理大量的文件夹&#xff0c;这时候掌握一些文件夹重命名的技巧就非常实用。例如文件夹重命名时&#xff0c;经常要将一些通用的文字替换成其他关键词&#xff0c;以便更好地标识和分类文件夹。而用关键词替换文件夹名称指定内容的右侧文字&…

智能优化算法应用:基于纵横交叉算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于纵横交叉算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于纵横交叉算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.纵横交叉算法4.实验参数设定5.算法结果6.参考…

亚马逊云科技re:Invent Peter DeSantis演讲,数据规模拓展无极限引领Serverless构建之路

re:lnvent 2023 Peter DeSantis主题演讲&#xff0c;数据规模拓展无极限引领Serverless构建之路&#xff08;Road to Serverless&#xff09;。 Logical Qubit全新发布&#xff1a;量子计算硬件&#xff0c;6倍的量子纠错效率提升。 Amazon全新发布Redshift Serverless&#xf…