Redis 介绍(来自于百度百科)
redis是一个key-value存储系统。
它和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。
这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。
在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部 分场合可以对关系数据库起到很好的补充作用。它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等客户端,使用很方便。
Redis支持主从同步。数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。
这使得Redis可执行单层树复制。存盘可以有意无意的对数据进行写操作。由于完全实现了发布/订阅机制,使得从数据库在任何地方同步树时,可订阅一个频道并接收主服务器完整的消息发布记录。同步对读取操作的可扩展性和数据冗余很有帮助。
Spring Boot介绍(来自于百度百科)
SpringBoot是由Pivotal团队在2013年开始研发、2014年4月发布第一个版本的全新开源的轻量级框架。它基于Spring4.0设计,不仅继承了Spring框架原有的优秀特性,而且还通过简化配置来进一步简化了Spring应用的整个搭建和开发过程。另外SpringBoot通过集成大量的框架使得依赖包的版本冲突,以及引用的不稳定性等问题得到了很好的解决。
接下来我们使用Spring Boot 集成Redis
怎么配置Redis 可查看此篇博客 https://blog.csdn.net/weixin_53284329/article/details/112275460
首先第一步我们在pom 文件中加入所需要的依赖:
<dependencies>
<!-- spring boot 缓存 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!-- 集成redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Boot -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
<!-- 热部署 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!-- MySQL -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- get/set -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- 可不加 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
然后写配置
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/sys?serverTimezone=UTC&nullCatalogMeansCurrent=true
spring.datasource.username=root
spring.datasource.password=123456
mybatis.type-aliases-package=com.example.domain
mybatis.mapper-locations=classpath:mapper/*.xml
logging.level.com.example.dao=debug
#可加可不加
spring.cache.type=redis
## Redis 配置
## Redis数据库索引(默认为0)
spring.redis.database=0
## Redis服务器地址
spring.redis.host=127.0.0.1
## Redis服务器连接端口
spring.redis.port=6379
## Redis服务器连接密码(默认为空)
spring.redis.password=
## 连接池最大连接数(使用负值表示没有限制)
spring.redis.pool.max-active=8
## 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.pool.max-wait=-1
## 连接池中的最大空闲连接
spring.redis.pool.max-idle=8
## 连接池中的最小空闲连接
spring.redis.pool.min-idle=0
## 连接超时时间(毫秒)
spring.redis.timeout=0
实体类:
package com.example.domain;
import java.io.Serializable;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User implements Serializable{
private Integer id;
private String username;
private String password;
}
下面需要一个Redis配置类如下:
package com.example.config;
import java.net.UnknownHostException;
import java.time.Duration;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
@Configuration
@EnableCaching // 开启注解式缓存
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
//创建一个redis操作模板
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
//设置一个工厂
redisTemplate.setConnectionFactory(redisConnectionFactory);
//json的序列化器
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
redisTemplate.setDefaultSerializer(jackson2JsonRedisSerializer);
//返回redis操作模板
return redisTemplate;
}
/**
* 缓存管理器,将默认的缓存管理器设置成自定义的缓存管理器
* @param factory
* @return
*/
@Bean
public CacheManager cacheManager(RedisConnectionFactory factory) {
RedisSerializer<String> redisSerializer = new StringRedisSerializer();
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
//解决查询缓存转换异常的问题
ObjectMapper om = new ObjectMapper();
//序列列化所有属性PropertyAccessor.ALL
//所有的属性包含私有的等 JsonAutoDetect.Visibility.ANY
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
// 配置序列化(解决乱码的问题),过期时间30秒
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofSeconds(30))
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
.disableCachingNullValues();
RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
.cacheDefaults(config)
.build();
return cacheManager;
}
}
控制器:
package com.example.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.example.domain.User;
import com.example.service.UserService;
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userservice;
@RequestMapping("/findUserByid")
public User findUserByid(int id) {
return userservice.findUserByid(id);
}
}
Service:
package com.example.service;
import com.example.domain.User;
public interface UserService {
User findUserByid(int id);
}
package com.example.serviceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.example.dao.UserMapper;
import com.example.domain.User;
import com.example.service.UserService;
@Service
@Transactional
public class UserServiceImpl implements UserService{
@Autowired
private UserMapper usermapper;
@Override
@Cacheable(value = "user",key = "#id",unless = "#result == null")
public User findUserByid(int id) {
return usermapper.findUserByid(id);
}
}
dao 层:
package com.example.dao;
import com.example.domain.User;
public interface UserMapper {
User findUserByid(int id);
}
<?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.example.dao.UserMapper">
<select id="findUserByid" resultType="user" parameterType="int">
select * from sys_user where id = #{id}
</select>
</mapper>
接下来我们来测试一下:
看一下sql 执行情况:
再看一下redis
东西已经存进来了,我们再刷新一下页面,可以看到
我们可以看到第二次执行查询的时候是没有sql 执行情况的
写了查询,我们把修改和删除也写一下
controller :
package com.example.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.example.domain.User;
import com.example.service.UserService;
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userservice;
@RequestMapping("/findUserByid")
public User findUserByid(int id) {
return userservice.findUserByid(id);
}
@RequestMapping("/update")
public int update(User user) {
return userservice.update(user)==null?0:1;
}
@RequestMapping("/delete")
public int delete(int id) {
return userservice.deleteStudent(id);
}
}
Service:
package com.example.service;
import com.example.domain.User;
public interface UserService {
User findUserByid(int id);
Object update(User user);
int deleteStudent(int id);
}
package com.example.serviceImpl;
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.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.example.dao.UserMapper;
import com.example.domain.User;
import com.example.service.UserService;
@Service
@Transactional
public class UserServiceImpl implements UserService{
@Autowired
private UserMapper usermapper;
@Override
@Cacheable(value = "user",key = "#id",unless = "#result == null")
public User findUserByid(int id) {
return usermapper.findUserByid(id);
}
@Override
@CachePut(value = "user",key = "#user.id",unless="#result == null")
public Object update(User user) {
int row=usermapper.update(user);
if(row==0) {
return null;
}else {
return this.findUserByid(user.getId());
}
}
@Override
@CacheEvict(value = "user", key = "#id")//删除数据之后,清除缓存
public int deleteStudent(int id) {
// TODO Auto-generated method stub
return usermapper.deleteUserById(id);
}
}
Dao:
package com.example.dao;
import com.example.domain.User;
public interface UserMapper {
User findUserByid(int id);
int update(User user);
int deleteUserById(int id);
}
<?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.example.dao.UserMapper">
<select id="findUserByid" resultType="user" parameterType="int">
select * from sys_user where id = #{id}
</select>
<update id="update" parameterType="user">
update sys_user
<trim prefix="set" suffixOverrides=",">
<if test="username!=null and username!=''">username=#{username},</if>
<if test="password!=null and password!=''">password=#{password},</if>
</trim>
where id=#{id}
</update>
<delete id="deleteUserById" parameterType="int">
delete from sys_user where id=#{id}
</delete>
</mapper>
效果大家就自己试吧