springboot整合redis
提前准备
sql文件和源码地址:git clone https://gitee.com/xinhe66/springboot-redis.git
项目列表
文章目录:
一.Pom文件导入依赖
二.配置application.properties文件
三.新建一个User对象
四.server层内容
五.controller层内容
六.mapper层内容
七.RedisConfig配置
八.简单测试
九.总结
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.sc</groupId>
<artifactId>testRedis</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.1.3.RELEASE</version>
</dependency>
<!-- 添加MyBatis依赖 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.0</version>
</dependency>
<dependency>
<groupId>MysqL</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>6.0.5</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
<version>2.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>1.5.18.RELEASE</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.24</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.8</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>27.0-jre</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.18</version>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<!-- 此配置不可缺,否则mybatis的Mapper.xml将会丢失 -->
<includes>
<include>**/*.xml</include>
</includes>
</resource>
<!--指定资源的位置-->
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.yml</include>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
二.配置application.properties文件
server:
port: 8181
# context-path: /tsl
spring:
resources:
static-locations: classpath:static/
#配置rabbitMq 服务器
rabbitmq:
host: 127.0.0.1
port: 15672
username: guest
password: guest
listener:
simple:
auto-startup: false
aop:
auto: true
proxy-target-class: true
redis:
host: 127.0.0.1
port: 6379
database: 5
jedis:
pool:
max-idle: 8
min-idle: 1
max-active: 8
max-wait: -1
timeout: 2000
datasource:
# 数据源基本配置
username: root
password: a123
driver-class-name: com.MysqL.cj.jdbc.Driver
url: jdbc:MysqL://localhost:3306/testRedis?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone = GMT
# 数据源其他配置
initialSize: 5
minIdle: 5
maxActive: 20
maxWait: 60000
timeBetweenevictionRunsMillis: 60000
minevictableIdleTimeMillis: 300000
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
filters: stat,wall,log4j
maxPoolPreparedStatementPerConnectionSize: 20
useglobalDataSourceStat: true
connectionProperties: druid.stat.mergesql=true;druid.stat.slowsqlMillis=500
mybatis:
# 指定全局配置文件位置
config-location: classpath:config/mybatis-config.xml
# 指定sql映射文件位置
mapper-locations: classpath:mapper/*.xml
三.新建一个User对象
User对象一定要实现序列化接口(Serializable )否则redis缓存时会报错
package com.sc.domain;
import java.io.Serializable;
public class User implements Serializable {
private String id;
private String userName;
private String userPwd;
private Integer age;
private String address;
public User(String id, String userName, String userPwd, Integer age, String address) {
super();
this.id = id;
this.userName = userName;
this.userPwd = userPwd;
this.age = age;
this.address = address;
}
public User() {
super();
// Todo Auto-generated constructor stub
}
public String getId() {
return id;
}
public void setId(String 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;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "User [id=" + id + ", userName=" + userName + ", userPwd=" + userPwd + ", age=" + age + ", address="
+ address + "]";
}
}
四.server层内容
server层
package com.sc.service;
import com.sc.domain.User;
import com.sc.mapper.UserMapper;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheevict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
/**
* 缓存机制是作用到Service层的,
* 而dao或者repository层缓存用注解,用key的话它会认定为null。
* 要用KeyGenerator来提前生成key的生成策略
* @author linhaiy
*
*/
public interface UserService {
public List<User> findList();
public User findById(String id);
public User AddUser(User user);
public void deleteUser(String id);
public User updatePwdById(User user);
public User queryUserByIdCondition(String id);
}
serverImpl层
package com.sc.service.impl;
import com.sc.domain.User;
import com.sc.mapper.UserMapper;
import com.sc.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheevict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
@CacheConfig(cacheNames = "user")
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
@Cacheable(value="user")
public List<User> findList() {
return userMapper.findList();
}
@Override
@Cacheable(cacheNames="user",key ="#id")
public User findById(String id) {
return userMapper.findById(id);
}
/**
* acheNames 设置缓存的值
* key:指定缓存的key,这是指参数id值。 key可以使用spEl表达式,也可以是指定对象的成员变量
* @param user
*/
@Override
@CachePut(cacheNames="user",key = "#user.id")
public User AddUser(User user) {
int i = userMapper.AddUser(user);
if(i>0){
return user;
}
return null;
}
//如果指定为 true,则方法调用后将立即清空所有缓存
@Override
@Cacheevict(key ="#id",allEntries=false)
public void deleteUser(String id) {
userMapper.deleteUser(id);
}
@Override
@CachePut(cacheNames="user",key = "#user.id")
public User updatePwdById(User user) {
int i = userMapper.updatePwdById(user);
if(i>0){
return user;
}
return null;
}
/**
* 条件缓存:
* 只有满足condition的请求才可以进行缓存,如果不满足条件,则跟方法没有@Cacheable注解的方法一样
* 如下面只有id < 3才进行缓存
* @param id
* @return
*/
@Override
@Cacheable(cacheNames = "user", key = "#id", condition = "T(java.lang.Integer).parseInt(#id) < 3 ")
public User queryUserByIdCondition(String id) {
return userMapper.findById(id);
}
}
五.controller层内容
package com.sc.conntroller;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import com.sc.domain.User;
import com.sc.service.UserService;
import com.sc.util.ResponseResult;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
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;
import org.springframework.web.bind.annotation.RestController;
import com.alibaba.fastjson.JSONObject;
/**
* 用户缓存测试类
* @author linhaiy
* @date 2019.03.05
*/
@RestController
@RequestMapping(value = "/userCache")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/findList")
@ResponseBody
public JSONObject findList(HttpServletRequest request){
JSONObject rr = new JSONObject();
List<User> list = userService.findList();
if(list !=null && list.size() >0) {
rr.put("state","0");
rr.put("msg","success");
rr.put("data", list);
}
return rr;
}
@RequestMapping("/findById")
@ResponseBody
public ResponseResult<User> findById(@RequestParam String id){
ResponseResult<User> resData = new ResponseResult<User>();
User user = userService.findById(id);
resData.setStatus(0);
resData.setMessage("success");
resData.setData(user);
return resData;
}
@RequestMapping("/queryUserByIdCondition")
@ResponseBody
public ResponseResult<User> queryUserByIdCondition(@RequestParam String id){
ResponseResult<User> resData = new ResponseResult<User>();
User user = userService.queryUserByIdCondition(id);
resData.setStatus(0);
resData.setMessage("success");
resData.setData(user);
return resData;
}
@RequestMapping(value = "AddUser",method= RequestMethod.POST)
@ResponseBody
public JSONObject AddUser(User user){
JSONObject rr = new JSONObject();
try {
if(user !=null) {
userService.AddUser(user);
rr.put("state","0");
rr.put("msg","success");
}else {
rr.put("state","2");
rr.put("msg","参数错误");
}
} catch (Exception e) {
// Todo Auto-generated catch block
rr.put("state","2");
rr.put("msg","保存用户信息失败");
e.printstacktrace();
}
return rr;
}
@RequestMapping(value = "deleteUser",method= RequestMethod.POST)
@ResponseBody
public JSONObject deleteUser(@RequestParam String id){
JSONObject rr = new JSONObject();
try {
if(StringUtils.isNotBlank(id)) {
userService.deleteUser(id);
rr.put("state","0");
rr.put("msg","用户信息删除成功");
}else {
rr.put("state","2");
rr.put("msg","参数输入错误");
}
} catch (NumberFormatException e) {
// Todo Auto-generated catch block
rr.put("state","2");
rr.put("msg","用户操作错误");
}
return rr;
}
@RequestMapping(value = "updatePwdById",method= RequestMethod.POST)
@ResponseBody
public JSONObject updatePwdById(User user){
JSONObject rr = new JSONObject();
try {
if(user !=null) {
if(StringUtils.isNotBlank(user.getUserPwd())) {
userService.updatePwdById(user);
rr.put("state","0");
rr.put("msg","用户密码修改成功");
}else {
rr.put("state","2");
rr.put("msg","参数错误");
}
}else {
rr.put("state","2");
rr.put("msg","没有修改数据");
}
} catch (Exception e) {
// Todo Auto-generated catch block
rr.put("state","2");
rr.put("msg","用户操作错误");
e.printstacktrace();
}
return rr;
}
}
六.mapper层内容
package com.sc.mapper;
import java.util.List;
import com.sc.domain.User;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserMapper {
public List<User> findList();
public User findById(String id);
public int AddUser(User user);
public void deleteUser(String id);
public int updatePwdById(User user);
}
<?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.sc.mapper.UserMapper">
<sql id="userColumns">
a.id as "id",
a.user_name as "userName",
a.user_pwd as
"userPwd",
a.age as "age",
a.address as "address"
</sql>
<sql id="userJoins">
</sql>
<!-- 根据id查询用户表 -->
<select id="findById"
resultType="com.sc.domain.User"
parameterType="java.lang.String">
SELECT
<include refid="userColumns" />
FROM user a
<include refid="userJoins" />
WHERE a.id = #{id}
</select>
<select id="findList" resultType="com.sc.domain.User">
select * from user
</select>
<!-- 添加用户信息 -->
<insert id="AddUser">
INSERT INTO user(id,user_name,user_pwd,age,address)
VALUES
(#{id},#{userName},#{userPwd},#{age},#{address})
</insert>
<!-- 根据id删除对应的用户 -->
<delete id="deleteUser">
DELETE FROM user WHERE id = #{id}
</delete>
<!-- 修改用户密码 -->
<update id="updatePwdById">
UPDATE user SET user_pwd = #{userPwd} WHERE id = #{id}
</update>
</mapper>
七.RedisConfig配置
package com.sc.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
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.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.Redistemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.util.CollectionUtils;
import java.lang.reflect.Method;
import java.time.Duration;
/**
* Redis缓存配置类
* 初始化redis做数据缓存
* @author linhaiy
* @date 2019.03.05
*/
@Configuration
@EnableCaching
@Slf4j
public class RedisConfig extends CachingConfigurerSupport {
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private int port;
@Value("${spring.redis.timeout}")
private int timeout;
private static int OverTime = 1200000;
@Bean
@Primary
@Override //继承上面这个类,并且加上这个之后才能把它设置为默认的。
public KeyGenerator keyGenerator() {
return new KeyGenerator() {
@Override
public Object generate(Object target, Method method, Object... params) {
String re= String.format("%s::%s(%s)",target.getClass().getName(),method.getName(),
CollectionUtils.arrayToList(params));//Arrays.asList(params)
log.debug("缓存生成的key:{}。",re);
return re;
}
};
}
/**
* 缓存管理器(注意:此方法在SpringBoot2.0以下版本才有效,2.0以后得版本参照
* https://blog.csdn.net/Mirt_/article/details/80934312 来写)
* @param redistemplate
* @return
*/
// @Bean
// public CacheManager cacheManager(@SuppressWarnings("rawtypes") Redistemplate redistemplate) {
// RedisCacheManager cacheManager = new RedisCacheManager(redistemplate);
// cacheManager.setDefaultExpiration(OverTime); // 设置缓存过期时间
// return cacheManager;
// }
/*
* 缓存管理器(注意:此方法在SpringBoot2.0以上版本才有效
* */
@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
RedisCacheConfiguration cacheConfiguration =
RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofMinutes(10))
.disableCachingNullValues()
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new
GenericJackson2JsonRedisSerializer()));
return RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(cacheConfiguration).build();
}
/**
* 设置Redistemplate的序列化器。
* @param redisConnectionFactory
* @return
*/
@Bean
public Redistemplate<Object, Object> redistemplate(RedisConnectionFactory redisConnectionFactory) {
Redistemplate<Object, Object> redistemplate = new Redistemplate<Object, Object>();
redistemplate.setConnectionFactory(redisConnectionFactory);
// 使用Jackson2JsonRedisSerialize 替换默认序列化
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setobjectMapper(objectMapper);
// 设置value的序列化规则和 key的序列化规则
redistemplate.setValueSerializer(jackson2JsonRedisSerializer);
redistemplate.setKeySerializer(new StringRedisSerializer());
redistemplate.afterPropertiesSet();
return redistemplate;
}
}
八.简单测试
使用postman进行(新增)测试
使用rdm工具去查看缓存中是否存在新增内容
使用navicat查看数据库中是否存在user值
本文使用的是springboot+redis,使用的是注解的方式来实现redis缓存,整合其实不麻烦,网上好多博文都有。但是在配置RedisConfig时一定要小心,注意设置下key和value的序列化方式,不然存到Redis的中数据就是乱码的,还要可以自己定义key的生成方式。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。