SpringBoot如何使用redis
更新時(shí)間:2025年03月10日 10:02:55 作者:今天的接口寫(xiě)完了嗎?
文章主要介紹了如何在Spring Boot項(xiàng)目中配置Redis并解決亂碼問(wèn)題,同時(shí)提供了使用Redis操作不同類(lèi)型數(shù)據(jù)(如String、List、Hash、Set、ZSet和Bitmap)的代碼示例
一、pom.xml
<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>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>二、application.properties
# Redis服務(wù)器地址 spring.redis.host=192.168.11.84 # Redis服務(wù)器連接端口 spring.redis.port=6379 # Redis服務(wù)器連接密碼(默認(rèn)為空) spring.redis.password= # Redis數(shù)據(jù)庫(kù)索引(默認(rèn)為0) 共15個(gè) spirng.redis.database=0 ## 連接超時(shí)時(shí)間(毫秒) spring.redis.timout=30000 # 連接池最大連接數(shù)(使用負(fù)值表示沒(méi)有限制) 默認(rèn) 8 spring.redis.lettuce.pool.max-active=8 # 連接池中的最大空閑連接 默認(rèn) 8 spring.redis.lettuce.pool.max-idle=8 # 連接池中的最小空閑連接 默認(rèn) 0 spring.redis.lettuce.pool.min-idle=1 #連接池中最大空閑等待時(shí)間,3s沒(méi)有活干的時(shí)候直接驅(qū)逐該鏈接 spring.redis.lettuce.pool.min-evicate-idle-time-millis=3000 # 連接池最大阻塞等待時(shí)間(使用負(fù)值表示沒(méi)有限制) 默認(rèn) -1 spring.redis.lettuce.pool.max-wait=-1
三、編寫(xiě)一個(gè)配置類(lèi)用于解決亂碼問(wèn)題和對(duì)象真實(shí)的類(lèi)型問(wèn)題
package com.by.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
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.StringRedisSerializer;
import java.net.UnknownHostException;
@Configuration
public class RedisConfig {
@Bean
@ConditionalOnMissingBean(name = "redisTemplate")
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
// key序列化方式
template.setKeySerializer(StringRedisSerializer.UTF_8);
//Jackson2JsonRedisSerializer 序列化方式 來(lái)代替自來(lái)的jdk序列化方式,因?yàn)楹笳邥?huì)亂碼
Jackson2JsonRedisSerializer jack = new Jackson2JsonRedisSerializer(Object.class);
template.setValueSerializer(jack);
template.setHashKeySerializer(StringRedisSerializer.UTF_8);
template.setHashValueSerializer(jack);
/**
* 使用objeck設(shè)置對(duì)象的類(lèi)型為真實(shí)的對(duì)象類(lèi)型 而不是hsash
*/
ObjectMapper mapper=new ObjectMapper();
// 啟用默認(rèn)類(lèi)型推理,將類(lèi)型信息作為屬性寫(xiě)入JSON
// 就是把對(duì)象的全類(lèi)名寫(xiě)入json
mapper.activateDefaultTyping(mapper.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.NON_FINAL);
// 將類(lèi)型的信息作為屬性傳給json
jack.setObjectMapper(mapper);
return template;
}
}四、代碼案例
4.1 model 準(zhǔn)備 因?yàn)橛锌赡艽鎸?duì)象
- Student.java
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class Student implements Serializable {
private Integer id;
private String name;
}- Product.java
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class Product implements Serializable {
private Integer id;
private String name;
}4.2 使用redis 操作string
@Slf4j
@SpringBootTest
class StringTest {
/**
* 使用redis 操作string
*/
@Autowired
private StringRedisTemplate str;
// 自動(dòng)序列化,用 @Autowired報(bào)錯(cuò)
@Resource(name ="redisTemplate")
private RedisTemplate<String,Student> redisTemplate;
private final String key ="zhouxingxing";
/**
* 將對(duì)象序列化 不用手動(dòng)將對(duì)象轉(zhuǎn)成字符串
*/
@Test
void m8() {
// jdk 序列化
Student student = Student.builder().id(1).name("張三").build();
// JdkSerializationRedisSerializer serializer =new JdkSerializationRedisSerializer();
// byte[] serialize = serializer.serialize(student);
// String s=new String(serialize);
// s亂碼
redisTemplate.opsForValue().set("student", student);
Student student1 = redisTemplate.opsForValue().get("student");
System.out.println(student1.getName());
}
/**
* string里的get set 方法
*/
@Test
void m1() {
str.opsForValue().set("xiaolong", "帥呆了");
String xiaolong = str.opsForValue().get("xiaolong");
log.info("xiaolong:{}", xiaolong);
}
/**
* string里的strlen 方法
* append 方法:追加字符串
*/
@Test
void m2() {
str.opsForValue().set("xiaolong", "帥呆了");
String xiaolong = str.opsForValue().get("xiaolong");
log.info("xiaolong:{}", xiaolong);
// 追加字符串
str.opsForValue().append("xiaolong", "哈哈");
// 獲取長(zhǎng)度
Long size = str.opsForValue().size("xiaolong");
log.info("長(zhǎng)度為:{}", size);//15
}
/**
* string里的incr 方法
* incrBy 方法:增加指定值
*/
@Test
void m3() {
str.opsForValue().set("xiaolong", "100");
Long xiaolong = str.opsForValue().decrement("xiaolong", 2);
log.info("xiaolong:{}", xiaolong); //98
}
/**
* 將student 對(duì)象存到redis 里
* JSONUtil.toJsonStr(對(duì)象)--->將對(duì)象轉(zhuǎn)成序列化的json字符串
*/
@Test
void m4() {
Student student = Student.builder().id(1).name("張三").build();
str.opsForValue().set("student", JSONUtil.toJsonStr(student));
log.info("student:{}", str.opsForValue().get("student"));//student:{"id":1,"name":"張三"}
}
@Test
public void m7() {
str.opsForHash().put(key,"20220325","鄭州");
str.opsForHash().put(key,"20220326","洛陽(yáng)");
// 拿到所有小key的值
List<Object> values = str.opsForHash().values(key);
for (Object value : values) {
System.out.println(value);
}
}4.3 使用redis 操作list
@SpringBootTest
@Slf4j
public class ListTest {
@Autowired
private StringRedisTemplate redisTemplate;
private final String key = "xiaolong";
/**
* 給list左推元素和又推元素
* 從右方刪除元素并返回刪除的元素
*/
@Test
void m1() {
redisTemplate.opsForList().leftPush(key, "g1");
redisTemplate.opsForList().leftPush(key, "g2");
redisTemplate.opsForList().leftPush(key, "g3");
redisTemplate.opsForList().rightPush(key, "g4");//順序?yàn)?g3 g2 g1 g4
// 從右邊刪除元素 并返回刪除的元素
String s = redisTemplate.opsForList().rightPop(key);
log.info("刪除元素為:{}", s);// g4
}
@Test
public void m2() {
List<Object> obj = redisTemplate.executePipelined((RedisCallback<Object>) connection -> {
//隊(duì)列沒(méi)有元素會(huì)阻塞操作,直到隊(duì)列獲取新的元素或超時(shí)
return connection.bLPop(600, "list1".getBytes());
}, new StringRedisSerializer());
for (Object str : obj) {
System.out.println(str);
}
}4.4 使用redis 操作hash
@Slf4j
@SpringBootTest
public class HashTest {
@Autowired
private StringRedisTemplate redisTemplate;
// 自動(dòng)序列化
@Resource(name ="redisTemplate")
private RedisTemplate<String, Student> redisTemplate1;
// 設(shè)置大key
private final String key = "xiaolong";
@Test
void m10() {
Student student = Student.builder().id(1).name("張三").build();
redisTemplate1.opsForHash().put(key, "g1", student);
Object o = redisTemplate1.opsForHash().get(key, "g1");
}
// 設(shè)置商品黑名單
@Test
public void m9() {
Product p1 = Product.builder().id(1).name("華為").build();
Product p2 = Product.builder().id(2).name("小米").build();
redisTemplate1.opsForHash().put("黑名單","名單列表1",p1);
redisTemplate1.opsForHash().put("黑名單","名單列表2",p2);
}
/**
* 獲取大key里所有小key的值
*/
@Test
public void m1() {
redisTemplate.opsForHash().put(key, "g1", "小芳");
redisTemplate.opsForHash().put(key, "g2", "小紅");
// 拿到所有小key的值
List<Object> values = redisTemplate.opsForHash().values(key);
for (Object value : values) {
log.info("所有小key的值為:"+value);
}
}4.5 使用redis 操作set
@SpringBootTest
@Slf4j
public class SetTest {
@Autowired
private StringRedisTemplate redisTemplate;
private final String xiaoming = "xiaoming";
private final String xiaohong = "xiaohong";
@Test// 交集
void m1()
{
// 添加小明同學(xué)感興趣的學(xué)科
redisTemplate.opsForSet().add(xiaoming, "語(yǔ)文", "數(shù)學(xué)","物理");
// 添加小紅同學(xué)感興趣的學(xué)科
redisTemplate.opsForSet().add(xiaohong, "語(yǔ)文", "英語(yǔ)");
// 獲取兩位同學(xué)共同感興趣的學(xué)科
Set<String> tong = redisTemplate.opsForSet().intersect(xiaohong, xiaoming);
for (String s : tong) {
log.info("小明和小紅共同感興趣的學(xué)科為:"+s);// 語(yǔ)文
}
}
@Test//并集
void m2()
{
// 添加小明同學(xué)感興趣的學(xué)科
redisTemplate.opsForSet().add(xiaoming, "語(yǔ)文", "數(shù)學(xué)","物理");
// 添加小紅同學(xué)感興趣的學(xué)科
redisTemplate.opsForSet().add(xiaohong, "語(yǔ)文", "英語(yǔ)");
// 獲取兩位同學(xué)共同感興趣的學(xué)科
Set<String> tong = redisTemplate.opsForSet().union(xiaohong, xiaoming);
for (String s : tong) {
log.info("小明和小紅共同感興趣的學(xué)科為:"+s);// 語(yǔ)文
}
}4.6 使用redis 操作zset
@SpringBootTest
@Slf4j
public class ZsetTest {
@Autowired
private StringRedisTemplate redisTemplate;
@Resource(name = "redisTemplate")
private RedisTemplate<String, Integer> redisTemplate1;
private String key = "xiaolong";
/**
* zset有序集合唯一 去重 適用于今日頭條和熱搜
* 給xiaolong 添加三門(mén)得成績(jī)
*/
@Test
public void m1() {
redisTemplate.opsForZSet().add(key, "語(yǔ)文", 90);
redisTemplate.opsForZSet().add(key, "數(shù)學(xué)", 100);
redisTemplate.opsForZSet().add(key, "英語(yǔ)", 80);
Long aLong = redisTemplate.opsForZSet().zCard(key);
log.info("{科目數(shù)量為:}", aLong);
// 獲取xiaolong的最高分 spring 沒(méi)有給我們封裝
redisTemplate.execute(new RedisCallback<Object>() {
@Override
public Object doInRedis(RedisConnection connection) throws DataAccessException {
return connection.bLPop(5, key.getBytes());
}
});
}4.7 Redis 操作BitMap
@Component
public class BitMapDemo {
@Autowired
private StringRedisTemplate stringRedisTemplate;
private final String key ="sign#2022#zhouxingxing";
public void test(){
//設(shè)置簽到
stringRedisTemplate.opsForValue().setBit(key,2,true);
stringRedisTemplate.opsForValue().setBit(key,85,true);
//獲取周星星同學(xué)的簽到天數(shù)
RedisCallback<Long> callback = connection -> { return connection.bitCount(key.getBytes(),0,365);};
Long count = stringRedisTemplate.execute(callback);
//打印周星星2022年簽到天數(shù)
System.out.println("周星星2022年一共簽到天數(shù):"+count);
}
}總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
springboot項(xiàng)目啟動(dòng)后執(zhí)行方法的三種方式
有時(shí)項(xiàng)目需求,需要項(xiàng)目啟動(dòng)的時(shí)候向數(shù)據(jù)庫(kù)中查詢(xún)一下系統(tǒng)屬性,或者需要加載某個(gè)特定的方法,下面這篇文章主要給大家介紹了關(guān)于springboot項(xiàng)目啟動(dòng)后執(zhí)行方法的三種方式,需要的朋友可以參考下2022-06-06
springboot controller參數(shù)注入方式
這篇文章主要介紹了springboot controller參數(shù)注入方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-05-05
Spring Boot集成MinIO進(jìn)行文件存儲(chǔ)和管理的詳細(xì)步驟
這篇文章主要介紹了Spring Boot集成MinIO進(jìn)行文件存儲(chǔ)和管理的詳細(xì)步驟,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友一起看看吧2025-04-04
Java之ThreadPoolExecutor類(lèi)詳解
這篇文章主要介紹了Java之ThreadPoolExecutor類(lèi)詳解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-08-08
5分鐘快速學(xué)會(huì)spring boot整合JdbcTemplate的方法
這篇文章主要給大家介紹了如何通過(guò)5分鐘快速學(xué)會(huì)spring boot整合JdbcTemplate的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用spring boot整合JdbcTemplate具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12
MyBatis-Plus的物理刪除和邏輯刪除(使用場(chǎng)景)
數(shù)據(jù)庫(kù)中的數(shù)據(jù)刪除會(huì)分為兩種:物理刪除 和 邏輯刪除,接下來(lái)通過(guò)本文給大家介紹MyBatis-Plus的物理刪除和邏輯刪除使用場(chǎng)景分析,感興趣的朋友一起看看吧2021-09-09
Spring?Data?JPA框架快速入門(mén)之自定義Repository接口
Spring?Data?JPA是Spring基于JPA規(guī)范的基礎(chǔ)上封裝的?套?JPA?應(yīng)?框架,可使開(kāi)發(fā)者?極簡(jiǎn)的代碼即可實(shí)現(xiàn)對(duì)數(shù)據(jù)庫(kù)的訪問(wèn)和操作,本篇我們來(lái)了解Spring?Data?JPA框架的自定義Repository接口2022-04-04

