版权声明:本文为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