Spring Boot 整合 Spring Cache + Redis

Stella981
• 阅读 871

1.安装redis

  a.由于官方是没有Windows版的,所以我们需要下载微软开发的redis,网址:https://github.com/MicrosoftArchive/redis/releases

  b.解压后,在redis根目录打开cmd界面,输入:redis-server.exe redis.windows.conf,启动redis(关闭cmd窗口即停止)

2.使用

  a.创建SpringBoot工程,选择maven依赖

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

        .....

    </dependencies>

  b.配置 application.yml 配置文件

server:
  port: 8080
spring:
  # redis相关配置
  redis:
    database: 0
    host: localhost
    port: 6379
    password:
    jedis:
      pool:
        # 连接池最大连接数(使用负值表示没有限制)
        max-active: 8
        # 连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: -1ms
        # 连接池中的最大空闲连接
        max-idle: 5
        # 连接池中的最小空闲连接
        min-idle: 0
        # 连接超时时间(毫秒)默认是2000ms
    timeout: 2000ms
  # thymeleaf热更新
  thymeleaf:
    cache: false

  c.创建RedisConfig配置类

@Configuration
@EnableCaching  //开启缓存
public class RedisConfig {

    /**
     * 缓存管理器
     * @param redisConnectionFactory
     * @return
     */
    @Bean
    public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
        // 生成一个默认配置,通过config对象即可对缓存进行自定义配置
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
        // 设置缓存的默认过期时间,也是使用Duration设置
        config = config.entryTtl(Duration.ofMinutes(30))
                // 设置 key为string序列化
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
                // 设置value为json序列化
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer()))
                // 不缓存空值
                .disableCachingNullValues();

        // 对每个缓存空间应用不同的配置
        Map<String, RedisCacheConfiguration> configMap = new HashMap<>();
        configMap.put("userCache", config.entryTtl(Duration.ofSeconds(60)));

        // 使用自定义的缓存配置初始化一个cacheManager
        RedisCacheManager cacheManager = RedisCacheManager.builder(redisConnectionFactory)
                //默认配置
                .cacheDefaults(config)
                // 特殊配置(一定要先调用该方法设置初始化的缓存名,再初始化相关的配置)
                .initialCacheNames(configMap.keySet())
                .withInitialCacheConfigurations(configMap)
                .build();
        return cacheManager;
    }

    /**
     * Redis模板类redisTemplate
     * @param factory
     * @return
     */
    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);
        // key采用String的序列化方式
        template.setKeySerializer(new StringRedisSerializer());
        // hash的key也采用String的序列化方式
        template.setHashKeySerializer(new StringRedisSerializer());
        // value序列化方式采用jackson
        template.setValueSerializer(jackson2JsonRedisSerializer());
        // hash的value序列化方式采用jackson
        template.setHashValueSerializer(jackson2JsonRedisSerializer());
        return template;
    }

    /**
     * json序列化
     * @return
     */
    private RedisSerializer<Object> jackson2JsonRedisSerializer() {
        //使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值
        Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
        //json转对象类,不设置默认的会将json转成hashmap
        ObjectMapper mapper = new ObjectMapper();
        mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        serializer.setObjectMapper(mapper);
        return serializer;
    }

}

  d.创建entity实体类

public class User implements Serializable {

    private int id;
    private String userName;
    private String userPwd;

    public User(){}

    public User(int id, String userName, String userPwd) {
        this.id = id;
        this.userName = userName;
        this.userPwd = userPwd;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getUserPwd() {
        return userPwd;
    }

    public void setUserPwd(String userPwd) {
        this.userPwd = userPwd;
    }

}

  e.创建Service

@Service
public class UserService {

    //查询:先查缓存是是否有,有则直接取缓存中数据,没有则运行方法中的代码并缓存
    @Cacheable(value = "userCache", key = "'user:' + #userId")
    public User getUser(int userId) {
        System.out.println("执行此方法,说明没有缓存");
        return new User(userId, "用户名(get)_" + userId, "密码_" + userId);
    }

    //添加:运行方法中的代码并缓存
    @CachePut(value = "userCache", key = "'user:' + #user.id")
    public User addUser(User user){
        int userId = user.getId();
        System.out.println("添加缓存");
        return new User(userId, "用户名(add)_" + userId, "密码_" + userId);
    }

    //删除:删除缓存
    @CacheEvict(value = "userCache", key = "'user:' + #userId")
    public boolean deleteUser(int userId){
        System.out.println("删除缓存");
        return true;
    }

    @Cacheable(value = "common", key = "'common:user:' + #userId")
    public User getCommonUser(int userId) {
        System.out.println("执行此方法,说明没有缓存(测试公共配置是否生效)");
        return new User(userId, "用户名(common)_" + userId, "密码_" + userId);
    }

}

  f.创建Controller

@RestController
@RequestMapping("/user")
public class UserController {

    @Resource
    private UserService userService;

    @RequestMapping("/getUser")
    public User getUser(int userId) {
        return userService.getUser(userId);
    }

    @RequestMapping("/addUser")
    public User addUser(User user){
        return userService.addUser(user);
    }

    @RequestMapping("/deleteUser")
    public boolean deleteUser(int userId){
        return userService.deleteUser(userId);
    }

    @RequestMapping("/getCommonUser")
    public User getCommonUser(int userId) {
        return userService.getCommonUser(userId);
    }

}

@Controller
public class HomeController {
    //默认页面
    @RequestMapping("/")
    public String login() {
        return "test";
    }

}

  g.在 templates 目录下,写书 test.html 页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>test</title>
    <style type="text/css">
        .row{
            margin:10px 0px;
        }
        .col{
            display: inline-block;
            margin:0px 5px;
        }
    </style>
</head>
<body>
<div>
    <h1>测试</h1>
    <div class="row">
        <label>用户ID:</label><input id="userid-input" type="text" name="userid"/>
    </div>
    <div class="row">
        <div class="col">
            <button id="getuser-btn">获取用户</button>
        </div>
        <div class="col">
            <button id="adduser-btn">添加用户</button>
        </div>
        <div class="col">
            <button id="deleteuser-btn">删除用户</button>
        </div>
        <div class="col">
            <button id="getcommonuser-btn">获取用户(common)</button>
        </div>
    </div>
    <div class="row" id="result-div"></div>
</div>
</body>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script>
    $(function() {
        $("#getuser-btn").on("click",function(){
            var userId = $("#userid-input").val();
            $.ajax({
                url: "/user/getUser",
                data: {
                    userId: userId
                },
                dataType: "json",
                success: function(data){
                    $("#result-div").text("id[" + data.id + ", userName[" + data.userName + "], userPwd[" + data.userPwd + "]");
                },
                error: function(e){
                    $("#result-div").text("系统错误!");
                },
            })
        });
        $("#adduser-btn").on("click",function(){
            var userId = $("#userid-input").val();
            $.ajax({
                url: "/user/addUser",
                data: {
                    id: userId
                },
                dataType: "json",
                success: function(data){
                    $("#result-div").text("id[" + data.id + ", userName[" + data.userName + "], userPwd[" + data.userPwd + "]");
                },
                error: function(e){
                    $("#result-div").text("系统错误!");
                },
            })
        });
        $("#deleteuser-btn").on("click",function(){
            var userId = $("#userid-input").val();
            $.ajax({
                url: "/user/deleteUser",
                data: {
                    userId: userId
                },
                dataType: "json",
                success: function(data){
                    $("#result-div").text(data);
                },
                error: function(e){
                    $("#result-div").text("系统错误!");
                },
            })
        });
        $("#getcommonuser-btn").on("click",function(){
            var userId = $("#userid-input").val();
            $.ajax({
                url: "/user/getCommonUser",
                data: {
                    userId: userId
                },
                dataType: "json",
                success: function(data){
                    $("#result-div").text("id[" + data.id + ", userName[" + data.userName + "], userPwd[" + data.userPwd + "]");
                },
                error: function(e){
                    $("#result-div").text("系统错误!");
                },
            })
        });
    });
</script>
</html>

3.其他

  a.复合缓存(@Caching)与 全局缓存配置(@CacheConfig):

@RestController
@RequestMapping("/user2")
@CacheConfig(cacheNames = "userCache")  //全局缓存设置
public class UserController2 {

    @RequestMapping("/addUser")
    @Caching(   //复合缓存
            cacheable = {
                    @Cacheable(key="'user2:' + #user.id")
            },
            put = {
                    @CachePut(value = {"common", "common2"}, key="'common2:user2:' + #user.id"),
                    @CachePut(value = {"common3"}, key="'common3:user3:' + #user.id")
            }
    )
    public User addUser(User user){
        int userId = user.getId();
        System.out.println("添加缓存");
        return new User(userId, "用户名(add)_" + userId, "密码_" + userId);
    }

}

   访问 http://localhost:8080/user2/addUser?id=555 并使用 RedisDesktopManager 查看redis缓存

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Stella981 Stella981
3年前
Nginx + lua +[memcached,redis]
精品案例1、Nginxluamemcached,redis实现网站灰度发布2、分库分表/基于Leaf组件实现的全球唯一ID(非UUID)3、Redis独立数据监控,实现订单超时操作/MQ死信操作SelectPollEpollReactor模型4、分布式任务调试Quartz应用
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Damumu Damumu
1年前
初识Redis
Redis安装配置Redis官方网站:https://redis.io/注:redis官方没有提供windows版,微软提供了一个windows版本,在2016年后再没有更新。https://github.com/microsoftarchive/redi
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这