Redis——(7)redis作为mybatis缓存整合二级缓存的整合

news2024/12/26 12:43:01

1.作为mybits的缓存整合 

    1)用户第一次访问的时候获取数据库的值,再次访问时直接从缓存中获取数据

      2)设置缓存过期时间

      3)项目8080端口是对外端口(向外部暴露的端口),区别于内部进程号,查内部端口用ps -ef|grep port,查外部端口用lsof -i:port

判断进程是否正常启动

启动会有一段时间datasource

结果:

 

先从缓存中拿数据,找不到再从DB中刷数据

2.作为mybits的二级缓存的整合

 (1)springboot cache的使用:可以结合redis、ehcache等缓存

之前的操作;1)先到redis缓存中去取值

                      2)如果找不到到db中去取值

                      3)将db中的值刷到缓存

这3个步骤都是固定的所以就有了cache

        一级缓存是:sqlSession,sql建立连接到关闭连接的数据缓存

        二级缓存是:全局

   @CacheConfig(cacheNames="userInfoCache")  在同个redis里面必须唯一

   @Cacheable(查) :

   来划分可缓存的方法 - 即,结果存储在缓存中的方法,以便在后续调用(具有相同的参数)时,返回缓存中的值而不必实际执行该方法

@CachePut(修改、增加) :

    当需要更新缓存而不干扰方法执行时,可以使用@CachePut注释。也就是说,始终执行该方法并将其结果放入缓存中(根据@CachePut选项)

    @CacheEvict(删除) :

     对于从缓存中删除陈旧或未使用的数据非常有用,指示缓存范围内的驱逐是否需要执行而不仅仅是一个条目驱逐

    (2)springboot cache的整合步骤:

      1)引入pom.xml依赖:

   <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
   </dependency>

       2)开启缓存注解: @EnableCaching(RedisConfig类           配置类)

       3)在方法上面加入SpEL         

   @CacheConfig(cacheNames="userInfoCache")  在同个redis里面必须唯一             指定cache的名称       

@Cacheable(查) :

   来划分可缓存的方法 -

即,结果存储在缓存中的方法,以便在后续调用(具有相同的参数)时,返回缓存中的值而不必实际执行该方法

@CachePut(修改、增加) :

    当需要更新缓存而不干扰方法执行时,可以使用@CachePut注释。

也就是说,始终执行该方法并将其结果放入缓存中(根据@CachePut选项)

@CacheEvict(删除) :

     对于从缓存中删除陈旧或未使用的数据非常有用,指示缓存范围内的驱逐是否需要执行而不仅仅是一个条目驱逐

结果:

@Service
@CacheConfig(cacheNames="userInfoCache") // 本类内方法指定使用缓存时,默认的名称就是userInfoCache
@Transactional(propagation=Propagation.REQUIRED,readOnly=false,rollbackFor=Exception.class)
public class UserService {

    @Autowired
    private UserMapper userMapper;

    // 因为必须要有返回值,才能保存到数据库中,如果保存的对象的某些字段是需要数据库生成的,
    //那保存对象进数据库的时候,就没必要放到缓存了
    @CachePut(key="#p0.id")  //#p0表示第一个参数
    //必须要有返回值,否则没数据放到缓存中
    public User insertUser(User u){
        this.userMapper.insert(u);
        //u对象中可能只有只几个有效字段,其他字段值靠数据库生成,比如id
        return this.userMapper.find(u.getId());
    }


    @CachePut(key="#p0.id")
    public User updateUser(User u){
        this.userMapper.update(u);
        //可能只是更新某几个字段而已,所以查次数据库把数据全部拿出来全部
        return this.userMapper.find(u.getId());
    }

    @Nullable
    @Cacheable(key="#p0") // @Cacheable 会先查询缓存,如果缓存中存在,则不执行方法
    public User findById(String id){
        System.err.println("根据id=" + id +"获取用户对象,从数据库中获取");
        Assert.notNull(id,"id不用为空");
        return this.userMapper.find(id);
    }



    @CacheEvict(key="#p0")  //删除缓存名称为userInfoCache,key等于指定的id对应的缓存
    public void deleteById(String id){
        this.userMapper.delete(id);
    }

    //清空缓存名称为userInfoCache(看类名上的注解)下的所有缓存
    //如果数据失败了,缓存时不会清除的
    @CacheEvict(allEntries = true)
    public void deleteAll(){
        this.userMapper.deleteAll();
    }


    @Nullable
    @Cacheable(value = "UserInfoList", keyGenerator = "simpleKeyGenerator") // @Cacheable 会先查询缓存,如果缓存中存在,则不执行方法
    public User findByIdTtl(String id){
        System.err.println("根据id=" + id +"获取用户对象,从数据库中获取");
        Assert.notNull(id,"id不用为空");
        return this.userMapper.find(id);
    }

}

提问:springboot cache 存在什么问题,

                                        第一,生成key过于简单,容易冲突       userinfoCache::3  (同一个redis只能有一个名称 ) key+参数  

                                        第二,无法设置过期时间,默认过期时间为永久不过期            (上面的3中方法)

                                        第三,配置序列化方式,默认的是序列化JDKSerialazable            jackson/json

如果不设置序列化的化可能会造成乱码等格式的问题

     (3)springboot cache自定义项

        1)自定义KeyGenerator  

         

        2)自定义cacheManager,设置缓存过期时间

        3)自定义序列化方式,Jackson

使用方法:(前两个)

@Configuration
@EnableCaching
public class RedisConfig {
    public RedisTemplate<String,String> redisTemplate(RedisConnectionFactory factory){
        RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(factory);
        return redisTemplate;
    }
    @Bean
    public KeyGenerator simpleKeyGenerator() {
        return (o, method, objects) -> {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append(o.getClass().getSimpleName());
            stringBuilder.append(".");
            stringBuilder.append(method.getName());
            stringBuilder.append("[");
            for (Object obj : objects) {
                stringBuilder.append(obj.toString());
            }
            stringBuilder.append("]");

            return stringBuilder.toString();
        };
    }

    @Bean
    public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
        return new RedisCacheManager(
                RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory),
                this.getRedisCacheConfigurationWithTtl(600), // 默认策略,未配置的 key 会使用这个
                this.getRedisCacheConfigurationMap() // 指定 key 策略
        );
    }
/**
 *
 * 自定义某个key的过期时间
 */
    private Map<String, RedisCacheConfiguration> getRedisCacheConfigurationMap() {
        Map<String, RedisCacheConfiguration> redisCacheConfigurationMap = new HashMap<>();
        redisCacheConfigurationMap.put("UserInfoList", this.getRedisCacheConfigurationWithTtl(100));
        redisCacheConfigurationMap.put("UserInfoListAnother", this.getRedisCacheConfigurationWithTtl(18000));
        return redisCacheConfigurationMap;
    }
    /**
     *
     * 自定义序列化的方式
     */
    private RedisCacheConfiguration getRedisCacheConfigurationWithTtl(Integer seconds) {
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);

        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig();
        redisCacheConfiguration = redisCacheConfiguration.serializeValuesWith(
                RedisSerializationContext
                        .SerializationPair
                        .fromSerializer(jackson2JsonRedisSerializer)
        ).entryTtl(Duration.ofSeconds(seconds));

        return redisCacheConfiguration;
    }
}

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

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

相关文章

分布式环境下Spring Session Redis底层原理

1 自动装配 public class SessionAutoConfiguration {// SessionRepositoryFilterConfiguration用来配置核心的过滤器// 3 核心过滤器Configuration(proxyBeanMethods false)ConditionalOnWebApplication(type Type.SERVLET)Import({ ServletSessionRepositoryValidator.clas…

什么是代码签名证书?

使用代码签名证书&#xff0c;您可以保证签名者的身份和软件的完整性&#xff0c;这可以防止在下载和安装软件时出现警告。 代码签名证书是软件开发人员用来签署其软件、应用程序和驱动程序代码的数字证书。它使用公私密钥基础设施(PKI)将实体绑定到公钥和私钥。 申请代码签名…

SuperKnob超级旋钮

SuperKnob超级旋钮 2022年12月5日&#xff0c;今天总结下几个月前搞得小项目&#xff0c;好久没有写文总结了&#xff0c;有多少人不再写博客了呢&#xff1f;转眼疫情已三年&#xff0c;生活节奏太快了&#xff0c;认识的很多大佬他们的博客也不再更新了&#xff0c;都在努力…

Vue3 组件,一点也不难

Vue3 组件&#xff0c;一点也不难1.简介2.一个简单的 Vue 组件的实例3.局部组件4.Prop5.动态 Prop1.简介 组件是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素&#xff0c;封装可重用的代码。 组件系统让我们可以用独立可复用的小组件来构建大型应用&#xff0c;几乎任意…

jmeter压测mysql(保姆级教程)

准备工作&#xff08;下载mysql-connector&#xff09;&#xff1a; 打开mysql官网&#xff1a;MySQL 找到mysql connectors&#xff0c;选择操作系统独立版本&#xff0c;将下载jar包导入到jmeter的lib目录下。 参考文档&#xff1a;https://www.jb51.net/article/190860.h…

安装包UI美化之路-nsNiuniuSkin多语言配置

今天给大家带来的多语言配置功能&#xff0c;算是nsNiuniuSkin的一次质的提升&#xff0c;希望对大家有所帮助。 nsNiuniuSkin通过自研多语言配置引擎&#xff0c;让安装包的多语言配置不再复杂&#xff0c;直接设置语言翻译配置文件&#xff0c;即可实现安装包整体的多语言切…

一文读懂机智云物联网APP开发

本教程可用于C2 DevKit开发板套件全功能展示&#xff0c;用于对shineblink 的C2 DevKit开发套件全面学习使用&#xff0c;shineblink&及机智云技术交流群&#xff08;234976524&#xff09;。开发板相关的进阶教程及DIY应用将在后续持续更新。教程主要包含以下内容&#xf…

客户案例 | 举重若轻,低代码培育核心业务能力工坊

关键发现 用户痛点&#xff1a;传统套件式项目管理软件在中小企业或业务流程相对简单的企业中适配度低&#xff0c;不够灵活&#xff0c;性价比低&#xff0c;需要一套针对不同业务流程可以灵活配置的、轻量化的项目管理系统。 解决方案&#xff1a;基于西门子低代码开发平台…

六、Git远程仓库操作——创建远程库、推送拉取和克隆远程库等操作

1. 远程仓库介绍 前面的关于git的操作&#xff0c;都是基于本地仓库进行操作的。 但是如果我们想通过 Git 分享自己的代码或者与其他开发人员合作&#xff0c;这时我们就需要将数据放到一台其他开发人员能够连接的服务器上&#xff0c;这台服务器就是代码托管中心&#xff0c…

webpack热更新原理解析

热更新原理 1. webpack-dev-server启动本地服务 这里首先会启动webpack并生成compiler实例&#xff08;compiler实例通过各种事件钩子可以实现监听编译无效、编译结束等功能&#xff09;&#xff1b; 然后会通过express启动一个本地服务&#xff0c;用于服务浏览器对打包资源…

前端中的身份认证

一.Cookie 1.1.HTTP协议的无状态性 HTTP协议的无状态&#xff1a; 客户端的每次HTTP请求都是独立的&#xff0c;之间没有直接关系 服务器不会主动保留每次HTTP请求的状态 1.2.任何突破HTTP无状态的限制 发会员卡 注意&#xff1a; ​ 现实中,会员卡身份认证方式&#xff0c;在…

03 - 调试环境的搭建(Bochs)

---- 整理自狄泰软件唐佐林老师课程 1. Bochs&#xff08;另一款优秀的虚拟机软件&#xff09; 专业模拟x86架构的虚拟机 开源且高度可移植&#xff0c;由C编写完成 支持操作系统开发过程中的断点调试 通过简单配置就能运行绝大多数主流的操作系统 2. Bochs的安装与配置 下载…

[附源码]计算机毕业设计社区人员信息管理系统设计与实现Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

HRB系列直流隔离可调电源模块:用20K电位器和200K电位器区别

今天俞霖科技小编简谈如何合理地选用DC-DC模块电源&#xff0c;本文将从DC-DC模块电源开发设计的角度来简谈以上问题&#xff0c;以供广大技术设计人员参考。 DC-DC模块电源的众多优点是大家众所周知的&#xff0c;DC-DC模块电源以其体积小巧、性能卓异、使用方便的显著特点&a…

ArcGIS API For JavaScript(8)之使用动态图层dynamicLayers实现多图层合并截图

场景还原&#xff1a; 定位某个矢量图斑范围面&#xff0c;过滤展示该图斑&#xff0c;以图斑为中心&#xff0c;截图图斑周边并附带影像底图的截图。 在前端要实现地图截图&#xff0c;首先想到的是使用arcgis rest api中的export接口&#xff0c;这是没问题的&#xff0c;exp…

工业物联网关-modbus数据采集程序(1-程序设计)

写代码之前 最近代码写慢了&#xff0c;磨了好久都没开始动手写代码。考虑的东西越多越多&#xff0c;甚至自己都认为过虑了。就像这个程序&#xff0c;写代码之前估计花了大半天或者一天在思考怎么写&#xff0c;不知道是好事还是年纪大了。所以专门写篇文章&#xff0c;把自…

为什么要选择 Redis?

文章目录前言一、选型二、协议三、客户端1、常见 java 客户端2、常见可视化工具&#xff1a;四、Redis 生态1、模块2、代理3、其他前言 Redis&#xff08;Remote Dictionary Server&#xff09;&#xff0c;即「远程字典服务」是一个使用 ANSI C 编写的、开源的、支持网络的、…

【电力系统】基于YALMIP 的微网(光伏+风电+蓄电池+微电网+柴油机)优化调度模型附matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;修心和技术同步精进&#xff0c;matlab项目合作可私信。 &#x1f34e;个人主页&#xff1a;Matlab科研工作室 &#x1f34a;个人信条&#xff1a;格物致知。 更多Matlab仿真内容点击&#x1f447; 智能优化算法 …

Unity—UGUI

每日一句&#xff1a;读数、学习 去更远的地方&#xff0c;才能摆脱那些你不屑一顾的圈子 目录 InputFiled输入框 例&#xff1a;用户名和密码 Toggle组件 案例&#xff1a;冷却效果 InputFiled输入框 Text Component 输入文本组件 Text输入内容 Character Limit 输入字符…

宝塔后渗透-添加用户_反弹shell

更新时间&#xff1a;2022年11月21日 1. 背景介绍 对于想拿到bt后台来说&#xff0c;非常的艰难&#xff1a;无非是通过bypass之后提权&#xff0c;直接拿到服务器的root权限&#xff0c;然后再去宝塔后台。 当然&#xff0c;还有一种运气十分爆棚的方法&#xff1a;发现了b…