springboot整合cache+redis

news2024/12/30 3:53:05

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、cache是什么?
  • 二、使用步骤
    • 1.使用方式
        • 1.引入依赖
        • 2.搭建项目依赖问题
        • application.yml
        • TestController
        • TestService
        • TestServiceImpl
        • UserMapper
        • MyRedisConfig
        • userMapper
        • MybatisTest
  • 总结


前言

提示:这里可以添加本文要记录的大概内容:

springboot整合cache+redis


提示:以下是本篇文章正文内容,下面案例可供参考

一、cache是什么?

示例:springboot的缓存,提高了生产效率问题

二、使用步骤

1.使用方式

1.引入依赖

必须引入 cache2.2 和 redis依赖 2.2
否则会出现异常

  <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.7.7</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-cache -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
            <version>2.6.6</version>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.7.7</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.28</version>
        </dependency>

        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.2</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <version>2.7.7</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
            <version>2.6.6</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

2.搭建项目依赖问题

在这里插入图片描述

application.yml

server:
  port: 10001
spring:
  #解决循环依赖
  main:
    allow-circular-references: true
  #链接redis
  redis:
    host: 192.168.47.128
    port: 6379
  # 缓存类型
  cache:
    #缓存的时间
    redis:
      time-to-live: 180000
    type: redis
  datasource:
    url: jdbc:mysql://192.168.47.128:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC
    username: root
    password: 123456
    driver-class-name: com.mysql.jdbc.Driver
mybatis:
  mapper-locations: classpath:mapper/UserMapper.xml
  type-aliases-package: com.cn.pojo
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
#showSql
logging:
  level:
    com:
      example:
        mapper : debug

注意在修改的时候返回值必须是对象类型,否则会发现错误信息

TestController

import com.cn.pojo.TestUser;
import com.cn.service.TestService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;


@RestController
@RequestMapping("cache")
public class TestController {

    @Autowired
    private TestService testService;


    /**
     * 查询ID、信息
     * @param id
     * @return
     * 测试的方式
     * 1.发起请求第一从数据库中查询数据
     * 2.发起请求第二次从redis中查询数据
     */
    @GetMapping("/cacheFindById/{id}")
    public TestUser cacheFindById(@PathVariable("id") String id){
       TestUser user =testService.cacheFindById(id);
       return user;
    }

    /**
     * 更行成功
     * @param testUser
     * @return
     * 1.发送更新请求
     * 2.发送查询请求
     * 3.检查是否修改后的数据
     */
    @PostMapping("/cacheUpdate")
    public TestUser cacheUpdate(@RequestBody TestUser testUser){
        testService.cacheUpdate(testUser);
        return testUser;
    }

    /**
     * 删除
     * @param id
     * @return
     */
    @DeleteMapping("cacheDelete/{id}")
    public String cacheDelete(@PathVariable("id") String id ){
       int i =testService.cacheDelete(id);
       return "成功";
    }


}


TestService

public interface TestService {

    /**
     * value 存储空间
     * key 参数名称
     * 多个参数 通过+方式进行拼接 列如#id+#name
     * @param id
     * @return
     * unless 用于否决缓存的,不像condition,该表达式只在方 法执行之后判断,此时可以拿到返回值result进行判断。条件为true不会缓存,fasle才缓存
     */
    @Cacheable(value = "cacheFindById",key = "#id",unless = "#result==null")
    TestUser cacheFindById(String id);

    @CachePut(value = "cacheFindById",key = "#result.id")
    TestUser cacheUpdate(TestUser testUser);

    /**
     * 参数的说明方式
     * 出现异常是否清除缓存
     * beforeInvocation = true
     * 是否清除所有缓存
     * allEntries = true
     * @param id
     * @return
     */
    @CacheEvict(value = "cacheFindById",key = "#id")
    int cacheDelete(String id);

}

TestServiceImpl

import com.cn.mapper.UserMapper;
import com.cn.pojo.TestUser;
import com.cn.service.TestService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.stereotype.Service;



@Service
@CacheConfig
public class TestServiceImpl implements TestService {

    @Autowired
    private UserMapper userMapper;

    private Logger log = LoggerFactory.getLogger(TestServiceImpl.class);

    /**
     * 根据id查询方式
     * @param id
     * @return
     */
    @Override
    public TestUser cacheFindById(String id) {
        log.info("数据库查询方式,{}",id);
        System.out.println("查询ID为"+id);
        TestUser testUser =userMapper.cacheFindById(id);
        return testUser;
    }

    /**
     * 更新
     * @param testUser
     * @return
     */
    @Override
    public TestUser cacheUpdate(TestUser testUser) {
        userMapper.cacheUpdate(testUser);
        log.info("数据更行");
        return testUser;
    }

    /**
     * 删除
     * @param id
     * @return
     */
    @Override
    public int cacheDelete(String id) {
        int i=userMapper.cacheDelete(id);
        log.info("数据删除");
        return i;
    }


}


UserMapper


import com.cn.pojo.TestUser;

import java.util.List;

public interface UserMapper{

    List<TestUser> selectList();

    void BatchList(List<TestUser> testUserList);

    void cacheUpdate(TestUser testUser);

    int cacheDelete(String id);

    TestUser cacheFindById(String id);
}


出现乱码
在这里插入图片描述

MyRedisConfig

解决redis出现乱码问题

import com.cn.pojo.TestUser;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
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.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
public class MyRedisConfig {


    //Department的Redis序列化器
    @Bean
    public RedisTemplate<Object, TestUser> deptRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, TestUser> template = new RedisTemplate<>();
        Jackson2JsonRedisSerializer<TestUser> serializer = new Jackson2JsonRedisSerializer<TestUser>(TestUser.class);
        //根据源码查看可以自定义设置默认的序列化器
        template.setDefaultSerializer(serializer);
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }

    /**
     * 针对于Employee序列化的RedisCacheManager
     * @Bean 默认使用方法名作为bean的id
     * @param redisConnectionFactory
     * @return
     */
    @Primary
    @Bean
    public RedisCacheManager redisCacheManager(RedisConnectionFactory redisConnectionFactory){
        RedisCacheConfiguration configuration = RedisCacheConfiguration.defaultCacheConfig()
                //配置对key的序列化,这里使用string来序列化
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
                //配置对value的序列化,使用jsong来序列化
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new Jackson2JsonRedisSerializer<TestUser>(TestUser.class)))
                //不保存null值的缓存
                .disableCachingNullValues()
                //设置key的前缀 默认为: prefix + cache name + "::" + cache entry key
                .prefixCacheNameWith("->");

        RedisCacheManager cacheManager = RedisCacheManager.builder(redisConnectionFactory)
                //配置RedisCacheManager的相关配置信息并将缓存中的内容和spring中的事务同步
                .cacheDefaults(configuration).transactionAware().build();

        return cacheManager;
    }
}

userMapper

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cn.mapper.UserMapper">

    <insert id="BatchList" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
        INSERT INTO test_user (
        id,
        name,
        username,
        password,
        address
        ) VALUES
        <foreach item="data" collection="list" separator=",">
            (
            #{data.id},
            #{data.name},
            #{data.username},
            #{data.password},
            #{data.address}
            )
        </foreach>
    </insert>
    <update id="cacheUpdate">
          update test_user
            set
        <if test=" id !=null and id != '' ">
        id   = #{id},
        </if>
        name = #{name},
        username      = #{username},
        password  = #{password},
        address       = #{address}
    where id = #{id};
    </update>
    <delete id="cacheDelete">
        delete from test_user where id=#{id}
    </delete>


    <select id="selectList" resultType="com.cn.pojo.TestUser">
        select * from test_user
    </select>
    <select id="cacheFindById" resultType="com.cn.pojo.TestUser">
        select * from test_user where id =#{id}
    </select>
</mapper>

MybatisTest


import com.cn.mapper.UserMapper;
import com.cn.pojo.TestUser;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.util.StopWatch;

import java.util.ArrayList;
import java.util.List;

@SpringBootTest
@RunWith(SpringRunner.class)
public class MybatisTest {


    @Autowired
    private UserMapper userMapper;


    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private RedisTemplate<Object,TestUser> redisTemplate;

    private  Logger log = LoggerFactory.getLogger(MybatisTest.class);

    @Test
    public void test(){
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        List<TestUser> testUserList = new ArrayList<>();
        for (int i = 0; i <100000 ; i++) {
            TestUser testUser = new TestUser();
            testUser.setId(10000+i+"");
            testUser.setAddress("陕西北京"+i);
            testUser.setName("天天"+i);
            testUser.setPassword("123456"+i);
            testUser.setUsername("123456");
            testUserList.add(testUser);
        }
        stopWatch.stop();
        long lastTaskTimeMillis = stopWatch.getLastTaskTimeMillis();
        long totalTimeMillis = stopWatch.getTotalTimeMillis();
        log.info("时间"+lastTaskTimeMillis,lastTaskTimeMillis);
        log.debug("时间",lastTaskTimeMillis);
        System.out.println("lastTaskTimeMillis="+lastTaskTimeMillis);
        System.out.println("totalTimeMillis="+totalTimeMillis);
    }



    /**
     * 测试redis是否序列化
     */
    @Test
    public void redisIO(){
        TestUser testUser = new TestUser();
        testUser.setUsername("123");
        testUser.setPassword("234");
        testUser.setName("234");
        testUser.setAddress("sdf");
        testUser.setAddress("1");
        redisTemplate.opsForValue().set("emp",testUser);
    }




}


测试的url
保存
http://localhost:10001/cache/cacheUpdate
//查询
http://localhost:10001/cache/cacheFindById/15

总结

提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

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

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

相关文章

使用vue.component全局注册组件、props的使用

通过components注册的是私有子组件 例如&#xff1a; 在组件A的 components 节点下&#xff0c;注册了组件F。 则组件F只能用在组件A中;不能被用在组件C中。 注册全局组件 在vue项目的 main.js 入口文件中&#xff0c;通过 Vue.component() 方法&#xff0c;可以注册全局组件…

数据结构和算法学习记录——平衡二叉树(基本介绍、平衡因子、平衡二叉树的定义、平衡二叉树的高度)

目录 基本介绍 平衡因子 平衡二叉树 平衡二叉树的高度 基本介绍 什么是平衡二叉树&#xff1f; 以一个例子来解释一下&#xff1a; 搜索树结点按不同的插入次序&#xff0c;将会导致不同的深度和平均查找长度ASL 在二叉搜索树中查找一个元素&#xff1a; &#xff08…

TCP 协议的低效实现

包括 Linux kernel 在内的各种 TCP 实现均使用类似 skb 的对象管理一个个 packet&#xff0c;使 TCP 失去了 “流” 特征。应用通过 syscall 每写入一批数据&#xff0c;协议栈都可能生成一个 skb&#xff1a; ​ 仅管理这些 skb 就是一笔大开销。除了 skb 数据结构本身的 cru…

Python小姿势 - import requests

import requests Python中使用requests模块发送POST请求 在使用Python进行开发时&#xff0c;经常会遇到需要向某个网址发送POST请求的情况。这时候就需要使用到requests模块了。 requests模块是Python的一个标准模块&#xff0c;可以直接使用pip安装。 安装完成后&#xff0c;…

Java每日一练(20230425)

目录 1. 乘积最大子数组 &#x1f31f;&#x1f31f; 2. 插入区间 &#x1f31f;&#x1f31f; 3. 删除有序数组中的重复项 II &#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏…

CesiumForUnreal之3DTileset点选拾取属性与单体高亮

文章目录 1.实现目标2.实现过程2.1 3DTiles数据准备2.2 属性拾取2.3 单体高亮3.参考资料1.实现目标 在UE5中使用CesiumForUnreal插件加载本地的3dTiles建筑白模数据,实现点击拾取3DTileset单体要素的属性数据,并对高亮单体进行展示,GIF动图如下: 2.实现过程 总体的实现过程…

模型剪枝网络 Learning Efficient Network throung Network Slimming 简述

1. 概述 训练得到的特征图&#xff0c;并不是所有特征图都重要&#xff0c;另一方面&#xff0c;希望对权重执行策略&#xff0c;体现出权重之间的差异性&#xff0c;最终目的就是获得不同特征图中的channel sacling factors&#xff0c;表征了不同特征图的重要性 2. BN 采…

老码农眼中的大模型(LLM)

即便全力奔跑&#xff0c;也不一定能跟上时代的步伐。但如果失去了学习的动力&#xff0c;很可能会被时代淘汰。而且&#xff0c;当时代淘汰我们的时候&#xff0c;往往不会有任何预警。基于大模型的 ChatGPT 给我们带来了极大的震撼&#xff0c;那么什么是大模型呢&#xff1f…

【网络进阶】五种IO网络模型(一)

文章目录 1. 阻塞IO2. 非阻塞IO 1. 阻塞IO 在Linux中&#xff0c;默认情况下&#xff0c;所有的套接字&#xff08;socket&#xff09;都是阻塞的。典型的读取操作流程如下&#xff1a; 当用户进程调用read系统调用时&#xff0c;内核开始执行I/O的第一个阶段&#xff0c;即…

智慧医院智能化系统设计与能耗管理产品选型

摘要&#xff1a;结合某知名大型三甲综合医院项目的智能化系统设计&#xff0c;提出智慧医院智能化系统的技术解决方案&#xff0c;阐述智慧医院智能化系统方案的总体架构、建设目标、设计宗旨、典型应用及各智能化子系统的设计方案。 关键词&#xff1a;智慧医院&#xff1b;智…

mybatis3源码篇(2)——执行流程

mybatis 版本&#xff1a;v3.3.0 文章目录 执行流程MapperProxyFactoryMapperProxyMapperMethodexecuteconvertArgsToSqlCommandParamResultHandler SqlSessionExecutor&#xff08;执行器&#xff09;StatementHandler&#xff08;声明处理器&#xff09;ParameterHandler&…

【设计模式】我对设计模式的C语言解读(下)

书接上回 由于内容太多&#xff0c;编辑器太卡了&#xff0c;所以分P了 上P在这里 目录 书接上回备忘录模式观察者模式 备忘录模式 备忘录模式的介绍: https://refactoringguru.cn/design-patterns/memento 备忘录模式的C实现: https://refactoringguru.cn/design-patterns/m…

【数据挖掘与商务智能决策】第十三章 数据降维之PCA 主成分分析

13.1.2 PCA主成分分析代码实现 1.二维空间降维Python代码实现 import numpy as np X np.array([[1, 1], [2, 2], [3, 3]]) Xarray([[1, 1],[2, 2],[3, 3]])# 也可以通过pandas库来构造数据&#xff0c;效果一样 import pandas as pd X pd.DataFrame([[1, 1], [2, 2], [3, 3…

二分查找【数组】

⭐前言⭐ ※※※大家好&#xff01;我是同学〖森〗&#xff0c;一名计算机爱好者&#xff0c;今天让我们进入复习模式。若有错误&#xff0c;请多多指教。更多有趣的代码请移步Gitee &#x1f44d; 点赞 ⭐ 收藏 &#x1f4dd;留言 都是我创作的最大的动力&#xff01; 题目 70…

接口测试用例设计思路

&#xff08;我的公众号“墨石测试攻略”&#xff0c;关注获取软件测试相关知识及整套接口测试实战项目&#xff01;&#xff09; 接口测试用例的设计&#xff0c;从功能测试角度来说&#xff1a;首先需要分析接口文档。 现在很多公司都使用swagger来管理接口。swagger中可以…

fMRI时间序列振幅和相位对功能连接分析的影响

导读 目的&#xff1a;fMRI领域的一些研究使用瞬时相位(IP)表征(源自BOLD时间序列的解析表征)考察了脑区之间的同步性。本研究假设来自不同脑区的瞬时振幅(IA)表征可以为脑功能网络提供额外的信息。为此&#xff0c;本研究探索了静息态BOLD fMRI信号的这种表征&#xff0c;用于…

SpringBoot AnnotationFormatterFactory接口+自定义注解实现类型转换

参考资料 自定义AnnotationFormatterFactory实现注解方式类型转换Spring MVC 基于AnnotationFormatterFactory接口实现自定义的规则 目录 一. 前期准备1.1. 自定义转换标记注解1.2 入参form 二. 实现AnnotationFormatterFactory接口&#xff0c;构建格式化Factory2.1 code补全…

【7】一篇文章学习 Linux 中一些硬核的常用知识

目录 一、systemctl二、软链接三、日期&#xff08;date 命令&#xff09;四、Linux 的时区(1) 修改时区(2) ntp 五、IP 地址六、主机名七、域名解析八、配置 Linux 的固定 IP 地址(1) 在 VMwareWorkstation 中配置 IP 地址网关和网段&#xff08;IP 地址的范围&#xff09;(2)…

[陇剑杯 2021]之Misc篇(NSSCTF)刷题记录④

NSSCTF-Misc篇-[陇剑杯 2021] jwt&#xff1a;[陇剑杯 2021]jwt&#xff08;问1&#xff09;[陇剑杯 2021]jwt&#xff08;问2&#xff09;[陇剑杯 2021]jwt&#xff08;问3&#xff09;[陇剑杯 2021]jwt&#xff08;问4&#xff09;[陇剑杯 2021]jwt&#xff08;问5&#xff0…

洗地性价比高的是哪款?性价比高的洗地机推荐

在如今人工智能随处可见的时代&#xff0c;洗地机已经成为了我们家庭清洁的得力助手&#xff0c;它用高效便捷的清洁方式&#xff0c;对于地面的灰尘或者地板之间的缝隙里的细小垃圾&#xff0c;能够快速清理&#xff0c;省时省力。然而&#xff0c;对于很多消费者来说&#xf…