springboot2.x 和用redis做缓存的整合,有项目地址的呦

版权声明:本文为HCG原创文章,未经博主允许不得转载。请联系[email protected] https://blog.csdn.net/qq_39455116/article/details/84400852

1. springboot和用redis做缓存的整合

这里要整合的是springboot2.x和redis,所以你要把你的springboot 版本在开始之前换成springboot2.0之后的

具体怎么换其实就是换一下版本号,不换的话后面会有很多问题,楼主踩了无数坑

项目地址   https://github.com/HouChenggong/springboot_redis_cache.git

传送门

1.1 换版本号

//就是把version换成2.0以后的

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.0.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

1.2 添加maven的依赖

还会用到这三个maven依赖,总之先添加上把,后面会有用到的

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

1.3 数据库连接添加redis

spring:
  redis:
    host: 127.0.0.1
    port: 6379
    database: 2
    timeout: 60s  # 数据库连接超时时间,2.0 中该参数的类型为Duration,这里在配置的时候需要指明单位
    # 连接池配置,2.0中直接使用jedis或者lettuce配置连接池
    jedis:
      pool:
        # 最大空闲连接数
        max-idle: 8
        # 最小空闲连接数
        min-idle: 0
        # 等待可用连接的最大时间,负数为不限制
        max-wait:  -1s
        # 最大活跃连接数,负数为不限制
        max-active: -1
 

1.3 然后开启reidis缓存

package com.pf.org.cms;


import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;

import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;

import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;

import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.*;
import org.springframework.scheduling.annotation.EnableScheduling;

import javax.annotation.PostConstruct;
import java.lang.reflect.Method;
import java.time.Duration;

@EnableScheduling
@SpringBootApplication
@EnableCaching
public class CmsApplication {


    @Autowired
    private RedisConnectionFactory connectionFactory = null ;
    @Autowired
    private RedisTemplate redisTemplate ;


    //自定义初始化
    @PostConstruct
    public void init(){
        initRedisTemplate();
    }

    //改变redistemplate对于键的序列化策略
    private void initRedisTemplate(){
        RedisSerializer stringSerializer = redisTemplate.getStringSerializer();
        redisTemplate.setKeySerializer(stringSerializer);
        redisTemplate.setHashKeySerializer(stringSerializer);

    }

    public static void main(String[] args) {
        SpringApplication.run(CmsApplication.class, args);
    }
}

2. 添加代码实现

2.1 Entity

注意这里实现了序列化

public class MyRedisDO implements Serializable {


    private  Integer id ;

    private  String name ;


    private  String note ;
    
    getter and setter ....
    }

2.2 Mapper mapper.xml

import com.pf.org.cms.hcg.system.bean.MyRedisDO;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

@Mapper
public interface MyRedisMapper {

    int del(Integer id);

    int insert(MyRedisDO record);

    MyRedisDO selectById(Integer id);

   //获取用户id和user_name
    List<MyRedisDO> selectAll();

    int update(MyRedisDO record);

}
<?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.pf.org.cms.hcg.system.mapper.MyRedisMapper">
  <resultMap id="BaseResultMap" type="com.pf.org.cms.hcg.system.bean.MyRedisDO">
    <id column="id" jdbcType="INTEGER" property="id" />
    <result column="name" jdbcType="VARCHAR" property="name" />
    <result column="note" jdbcType="VARCHAR" property="note" />
  </resultMap>

  <sql id="Base_Column_List">
    id, name, note
  </sql>


  <select id="selectById" parameterType="java.lang.Integer" resultMap="BaseResultMap">
    select
    <include refid="Base_Column_List" />
    from myredis
    where id = #{id,jdbcType=INTEGER}
  </select>

  <insert id="insert" useGeneratedKeys="true"  keyColumn="id" keyProperty="id" parameterType="com.pf.org.cms.hcg.system.bean.MyRedisDO">
    insert into myredis (name ,note) values ( #{name,jdbcType=VARCHAR} ,#{note,jdbcType=VARCHAR})
  </insert>

  <update id="update" parameterType="com.pf.org.cms.hcg.system.bean.MyRedisDO">
    update  myredis set name =#{name,jdbcType=VARCHAR} , note =#{note,jdbcType=VARCHAR} WHERE  id =#{id}
  </update>

  <select id="selectAll" resultMap="BaseResultMap">
      select  * from  myredis
  </select>


  <delete id="del" parameterType="java.lang.Integer">
    delete  from  myredis
    where id =#{id}
  </delete>
</mapper>

2.3 service serviceImpl

public interface MyRedisService {
    MyRedisDO getById(Integer id);

    int delById(Integer id);

    MyRedisDO update(MyRedisDO myRedisDO);

    MyRedisDO insert(MyRedisDO myRedisDO);

    List<MyRedisDO> getAll();
}

注意@Service 、@Transactional和方法里面的

//针对查询的,如果缓存有要查询的值,直接从缓存中取,不进行方法查询
//如果缓存中没有,查询出来的数据,放到缓存中
@Cacheable(value = "redisCache", key = "'redisMyid'+#id")
// 将方法返回结果放到缓存中,一般用于更新
@CachePut(value = "redisCache", key = "'redisMyid'+#myRedisDO.id")
 //删除,beforeInvocation默认是false,表示在方法执行前或者方法执行后删除,一般也都是执行后删除
 //所以一般是false
 @CacheEvict(value = "redisCache",key = "'redisMyid'+#id", beforeInvocation = false)
至于里面的value和key不细说,可以百度一下
package com.pf.org.cms.hcg.system.service.impl;


import com.pf.org.cms.hcg.system.bean.MyRedisDO;
import com.pf.org.cms.hcg.system.mapper.MyRedisMapper;
import com.pf.org.cms.hcg.system.service.MyRedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

@Service
@Transactional
public class MyRedisServiceImpl implements MyRedisService {
    @Autowired
    private MyRedisMapper myRedisMapper;

    @Override
    @Cacheable(value = "redisCache", key = "'redisMyid'+#id")
    public MyRedisDO getById(Integer id) {
        System.out.println("查询"+new Date());
        return myRedisMapper.selectById(id);
    }

    @Override
    @CacheEvict(value = "redisCache",key = "'redisMyid'+#id", beforeInvocation = false)
    public int delById(Integer id) {
        return myRedisMapper.del(id);
    }

    @Override
    @CachePut(value = "redisCache", key = "'redisMyid'+#myRedisDO.id")
    public MyRedisDO update(MyRedisDO myRedisDO) {
        myRedisMapper.update(myRedisDO);
        return myRedisDO;
    }

    @Override
    @CachePut(value = "redisCache", key = "'redisMyid'+#myRedisDO.id")
    public MyRedisDO insert(MyRedisDO myRedisDO) {
        myRedisMapper.insert(myRedisDO);
        return myRedisDO;
    }

    @Override
    public List<MyRedisDO> getAll() {
        return myRedisMapper.selectAll();
    }
}

2.4 controller

package com.pf.org.cms.hcg.system.controller;


import com.pf.org.cms.hcg.system.bean.MyRedisDO;
import com.pf.org.cms.hcg.system.service.MyRedisService;
import com.pf.org.cms.manage.RedisManager;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * @author xiyou
 * @create 2017-11-21 17:08
 * @desc 系统管理控制层
 **/
@Api("用户管理的控制层")
@Controller
@RequestMapping("/redis/*")
public class RedisTestController {


    @Autowired
    RedisManager redisManager;

    @Autowired
    MyRedisService myRedisService;


    private static final Logger log = LoggerFactory.getLogger(UserController.class);


    @ApiOperation(value = "Redis测试接口", notes = "swagger测试接口")
    @RequestMapping(value = "/demo", method = RequestMethod.GET)
    @ResponseBody
    public String testRedis(
            @RequestParam("key") String key) {
        System.out.println("入参key为:" + key);
        String s = "查询结果为:" + redisManager.getStr(key);
        return s;
    }


    @ApiOperation(value = "Redis测试接口,Insert", notes = "Insert")
    @RequestMapping(value = "/demo/insertRedis", method = RequestMethod.GET)
    @ResponseBody
    public String redis1(
            @RequestParam("name") String name, @RequestParam("note") String note) {
        MyRedisDO myRedisDO = new MyRedisDO();
        myRedisDO.setName(name);
        myRedisDO.setNote(note);
        myRedisService.insert(myRedisDO);
        return "ok";
    }

    @ApiOperation(value = "Redis测试接口,get", notes = "get")
    @RequestMapping(value = "/demo/getRedis", method = RequestMethod.GET)
    @ResponseBody
    public String ge(
            @RequestParam("id") Integer id) {

        MyRedisDO redisDO = myRedisService.getById(id);
        MyRedisDO redisDO1 = myRedisService.getById(id);
        return redisDO.toString() + redisDO1.toString();
    }


    @ApiOperation(value = "Redis测试接口,del", notes = "del")
    @RequestMapping(value = "/demo/delRedis", method = RequestMethod.GET)
    @ResponseBody
    public int del(
            @RequestParam("id") Integer id) {

        int success = myRedisService.delById(id);
        return success;
    }

    @ApiOperation(value = "Redis测试接口,update", notes = "update")
    @RequestMapping(value = "/demo/updateRedis", method = RequestMethod.GET)
    @ResponseBody
    public MyRedisDO update(
            @RequestParam("id") Integer id) {
        MyRedisDO myRedisDO = myRedisService.getById(id);
        myRedisDO.setNote("更改");
        myRedisDO.setName("更改");
        myRedisService.update(myRedisDO);
        return myRedisDO;
    }
}


2.5 放开shiro拦截的接口

放开shiro拦截的接口,在shiroConfiguration里面
        filterChainDefinitionMap.put("/demo/**", "anon");
        filterChainDefinitionMap.put("/redis/**", "anon");
//访问进行接口测试
http://localhost:8080/swagger-ui.html#!/
http://localhost:8080/swagger-ui.html#!/redis-test-controller/geUsingGET

查询结果:

我们发现它存储的特别复杂而且没有过期时间,我们现在自定义redisCacheManager缓存管理器来管理

2.6 自定义缓存管理器来设置缓存时间并禁止前缀

在原来的application启动类里面添加

    @Bean(name = "redisCacheManager")
    public RedisCacheManager initRedisCacheManager(){
        //redis加锁的写入器
        RedisCacheWriter writer = RedisCacheWriter.lockingRedisCacheWriter(connectionFactory);
        //启动redis缓存的默认配置
        RedisCacheConfiguration configuration =RedisCacheConfiguration.defaultCacheConfig();
        //设置JDK序列化器
        configuration=configuration.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new JdkSerializationRedisSerializer()));
        //禁止前缀
        configuration =configuration.disableKeyPrefix();
        //设置10Min超时
        configuration= configuration.entryTtl(Duration.ofMinutes(10));
        //创建redis缓存管理器
        RedisCacheManager redisCacheManager = new RedisCacheManager(writer,configuration);
        return redisCacheManager ;

    }

结果如图:

至于乱码的问题,我们下期再说

项目地址   https://github.com/HouChenggong/springboot_redis_cache.git

传送门
































猜你喜欢

转载自blog.csdn.net/qq_39455116/article/details/84400852