整合 Redis
1 springboot整合redis
springboot在整合redis时提高两个模板类,StringRedisTemplate和RedisTemplate.以后对redis的操作都在该模板类中。StringRedisTemplate是RedisTemplate的子类。
<!--redis相关的依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
修改配置文件
#redis的配置信息
spring.redis.host=192.168.157.166
spring.redis.port=6379
#最多获取数
spring.redis.lettuce.pool.max-active=8
spring.redis.lettuce.pool.max-wait=-1ms
spring.redis.lettuce.pool.max-idle=8
spring.redis.lettuce.pool.min-idle=0
测试:
@SpringBootTest
class Qy163SpringbootRedisApplicationTests {
//因为springboot整合redis时会把StringRedisTemplate创建并交于spring容器管理
@Autowired
private StringRedisTemplate redisTemplate;
@Test
void contextLoads() {
ValueOperations operations = redisTemplate.opsForValue();
//查看redis中所有的key
System.out.println(redisTemplate.keys("*"));
//删除指定key的内容
// System.out.println(redisTemplate.delete("k1"));
//获取当前key的剩余时间
System.out.println(redisTemplate.getExpire("user"));
//判断key是否存在 返回0表示不存在,反之就是存在
System.out.println(redisTemplate.hasKey("k1"));
//String相关
//设置指定key的值
// operations.set("k4","1");
//获取指定key的值
Object k2 = operations.get("k2");
System.out.println(k2);
//同时设置一个或多个kv对
/*HashMap<Object, Object> map = new HashMap<>();
map.put("k01","01");
map.put("k02","02");
map.put("k03","03");
operations.multiSet(map);*/
//递增
/*operations.increment("k3");
Object k3 = operations.get("k3");
System.out.println(k3);*/
//递减
/*operations.decrement("k3");
Object k3 = operations.get("k3");
System.out.println(k3);*/
//只有在key不存在时设置key的值
/*Boolean aBoolean = operations.setIfAbsent("k1", "v1111");
System.out.println(aBoolean);*/
//Hash类型
HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
//将哈希表key中的字段field的值设为value
/*hash.put("hk1","name","xyz");
hash.put("hk1","age","18");
hash.put("hk1","sex","男");*/
//获取存储在哈希表中指定字段的值
System.out.println(hash.get("hk1", "name"));
//获取在哈希表中指定的key的所有字段和值
System.out.println(hash.entries("hk1"));
//获取所有哈希表中的字段
System.out.println(hash.keys("hk1"));
//获取哈希表中所有值
System.out.println(hash.values("hk1"));
//List相关
ListOperations<String, String> list = redisTemplate.opsForList();
//将一个或多个值插入到列表头部 可以重复值
/*Long aLong = list.leftPushAll("lk1", "xyz", "xqc", "zzz", "xxx", "ccc");
System.out.println(aLong);*/
//获取列表指定范围内的元素
System.out.println(list.range("lk1", 0, -1));
//从列表左侧移除第一个元素
//System.out.println(list.leftPop("lk1"));
//set相关 无须且不可重复的
SetOperations<String, String> forSet = redisTemplate.opsForSet();
//向集合添加一个或多个成员
/*Long add = forSet.add("sk1", "xyz", "xxx", "yyy", "zzz", "qqq");
System.out.println(add);*/
/*Long add = forSet.add("sk2", "xyz", "xxx", "fff", "hhh", "jjj");
System.out.println(add);*/
//返回集合中的所有成员
System.out.println(forSet.members("sk1"));
//随机获取一个或多个元素
System.out.println(forSet.randomMember("sk1"));
//返回指定所有集合的交集
System.out.println(forSet.intersect("sk1", "sk2"));
//sort set有序集合
//向有序集合添加一个或多个成员,或者个更新已存在成员的分数
/*ZSetOperations zSet = redisTemplate.opsForZSet();
zSet.add("zk1","数学",88.00d);
zSet.add("zk1","语文",88.50d);
zSet.add("zk1","英语",55.00d);
zSet.add("zk1","历史",99.00d);*/
//通过索引区间返回有序集合指定区间内的成员
// System.out.println(zSet.range("zk1", 0, -1));
}
}
1.2 RedisTemplate
它是StringRedisTemplate的父类,它类可以存储任意数据类型,但是任意类型必须序列化,默认采用的是jdk的序列化方式。jdk序列化方式阅读能力差,而且占用空间大. 我们在使用是一般需要人为指定序列化方式。
@SpringBootTest
class ApplicationTests2 {
@Autowired
private RedisTemplate redisTemplate;
//org.springframework.core.serializer.support.SerializationFailedException
//因为user对象在jvm内存中,---放入redis服务器---持久化到磁盘上。---要该对象的类必须序列化
//key和value都是乱码---因为它默认采用的序列化方式jdk的序列化方式。但是阅读不方便。我们一般不是jdk的序列化方式
@Test
public void test01(){
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
ValueOperations valueOperations = redisTemplate.opsForValue();
valueOperations.set("Class",new User(1,"阿童木","地球村"));
Object user = valueOperations.get("Class");
System.out.println(Class);
}
}
如果每次使用都人为指定序列化方式,统一设置redisTemplate的序列化
package com.zjy;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
/**
* @author:邹俊毅
* @create: 2023/4/24
**/
@Configuration
public class RedisConfig {
//比如验证码
@Bean //该方法的返回对象交于spring容器管理
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
RedisSerializer<String> redisSerializer = new StringRedisSerializer();
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
template.setConnectionFactory(factory);
//key序列化方式
template.setKeySerializer(redisSerializer);
//value序列化
template.setValueSerializer(jackson2JsonRedisSerializer);
//value hashmap序列化
template.setHashValueSerializer(jackson2JsonRedisSerializer);
//field序列化 key field value
template.setHashKeySerializer(redisSerializer);
return template;
}
}
上面的连接都是连接的单机版的redis,真实项目它们的redis都是集群模式.
1.3 springboot连接集群
spring.redis.lettuce.pool.max-active=8
spring.redis.lettuce.pool.max-wait=-1ms
spring.redis.lettuce.pool.max-idle=8
spring.redis.lettuce.pool.min-idle=0
# 设置redis重定向的次数---根据主节点的个数
spring.redis.cluster.max-redirects=3
spring.redis.cluster.nodes=192.168.157.166:7001,192.168.157.166:7002,192.168.157.166:7003,192.168.157.166:7004,192.168.157.166:7005,192.168.157.166:7006
4. redis的应用场景
4.1 redis可以作为缓存
(1) 缓存的原理
(2)缓存的作用:
减少访问数据库的频率。--提高系统的性能。
(3)什么样的数据适合放入缓存
- 查询频率高的
- 修改频率低的
- 数据安全性要求低的。
(4)如何使用缓存
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.12.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.zjy</groupId>
<artifactId>demo1</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>qy163-springboot-redis02</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<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>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
(3)配置文件
server.port=8888
spring.datasource.url=jdbc:mysql:///company
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
#redis的配置信息
spring.redis.host=192.168.157.166
spring.redis.port=6379
#最多获取数
spring.redis.lettuce.pool.max-active=8
spring.redis.lettuce.pool.max-wait=-1ms
spring.redis.lettuce.pool.max-idle=8
spring.redis.lettuce.pool.min-idle=0
(3)servie
import com.zjy.mapper.CourseinfoMapper;
import com.zjy.pojo.Courseinfo;
import com.zjy.service.CourseinfoService;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* @author 邹俊毅
* @description 针对表【courseinfo】的数据库操作Service实现
* @createDate 2023-04-25 08:49:18
*/
@Service
public class CourseinfoServiceImpl implements CourseinfoService {
@Resource
private CourseinfoMapper courseinfoMapper;
@Resource
private RedisTemplate<String, Object> redisTemplate;
@Override
public Courseinfo getById(Integer id) {
ValueOperations<String, Object> forValue = redisTemplate.opsForValue();
//1.查询缓存
Object o = forValue.get("courseinfo::" + id);
if(o!=null){ //缓存命中
return (Courseinfo) o;
}
Courseinfo courseinfo = courseinfoMapper.selectById(id);
//2.查询到应该放入缓存
if(courseinfo!=null){
forValue.set("dept::"+id,courseinfo);
}
return courseinfo;
}
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库