springboot2.x 和用redis做快取的整合,有專案地址的呦
阿新 • • 發佈:2018-12-12
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