前言
安裝 Redis
首先確認你的 Redis 服務已經啓動了。
這裏我在客戶端設置密碼爲 root。若不輸入密碼,是不能進行操作的,使用 auth root
之後就能進行操作了。
具體操作請參考:https://www.jianshu.com/p/0b03a3e05e1d
注意,我這裏的操作是沒有使用 auth 的。
redis 127.0.0.1:6379> config set requirepass root
OK
redis 127.0.0.1:6379> get *
(error) ERR operation not permitted
redis 127.0.0.1:6379> auth root
OK
redis 127.0.0.1:6379> get *
(nil)
redis 127.0.0.1:6379>
回顧一下Redis的存儲數據類型
結構類型 | 結構存儲的值 | 結構的讀寫能力 |
---|---|---|
String | 可以是字符串、整數或者浮點數 | 對整個字符串或者字符串的其中一部分執行操作;對象和浮點數執行自增(increment)或者自減(decrement) |
List | 一個鏈表,鏈表上的每個節點都包含了一個字符串 | 從鏈表的兩端推入或者彈出元素;根據偏移量對鏈表進行修剪(trim);讀取單個或者多個元素;根據值來查找或者移除元素 |
Set | 包含字符串的無序收集器(unorderedcollection),並且被包含的每個字符串都是獨一無二的、各不相同 | 添加、獲取、移除單個元素;檢查一個元素是否存在於某個集合中;計算交集、並集、差集;從集合裏賣弄隨機獲取元素 |
Hash | 包含鍵值對的無序散列表 | 添加、獲取、移除單個鍵值對;獲取所有鍵值對 |
Zset | 字符串成員(member)與浮點數分值(score)之間的有序映射,元素的排列順序由分值的大小決定 | 添加、獲取、刪除單個元素;根據分值範圍(range)或者成員來獲取 |
創建項目
然後在 idea 中創建一個 SpringBoot 項目,選擇NoSQL組件。
項目內容
resources 中
這個裏邊本來是要配置信息的,可本案例中使用代碼配置的方式。因此,這裏的配置信息就沒寫。
pom.xml 文件
本案例使用了 jedis 連接的方式,因爲 SpringData2.x中默認使用的是其他的連接方式,因此需要將其默認配置排除掉。再加入 jedis 的依賴,而 jedis 的依賴又需要 commons 這個依賴,所以這裏一併引入。
<?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.2.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>org.feng</groupId>
<artifactId>springdata-redis</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springdata-redis</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<exclusions>
<exclusion>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</exclusion>
<exclusion>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
RedisConfig
package org.feng.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.jedis.JedisClientConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.JedisPoolConfig;
/**
* Redis 配置類
*/
@Configuration
public class RedisConfig {
/**
* 創建JedisPoolConfig對象,在該對象中完成一些連接池配置
*/
@Bean
public JedisPoolConfig jedisPoolConfig () {
JedisPoolConfig config = new JedisPoolConfig();
// 配置最大空閒數
config.setMaxIdle(10);
// 配置最小空閒數
config.setMinIdle(5);
// 配置最大連接數
config.setMaxTotal(20);
return config;
}
@Bean
public RedisTemplate<String, Object> redisTemplate(JedisConnectionFactory jedisConnectionFactory){
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(jedisConnectionFactory);
// 設置 key 的序列化方式爲 String序列化器
redisTemplate.setKeySerializer(new StringRedisSerializer());
return redisTemplate;
}
@Autowired
public JedisConnectionFactory jedisConnectionFactory (JedisPoolConfig jedisPoolConfig) {
//單機版jedis
RedisStandaloneConfiguration redisStandaloneConfiguration =
new RedisStandaloneConfiguration();
//設置redis服務器的host或者ip地址
redisStandaloneConfiguration.setHostName("localhost");
//設置redis的服務的端口號
redisStandaloneConfiguration.setPort(6379);
//設置默認使用的數據庫
redisStandaloneConfiguration.setDatabase(0);
//設置密碼
// redisStandaloneConfiguration.setPassword("root");
//獲得默認的連接池構造器(怎麼設計的,爲什麼不抽象出單獨類,供用戶使用呢)
JedisClientConfiguration.JedisPoolingClientConfigurationBuilder jpcb =
(JedisClientConfiguration.JedisPoolingClientConfigurationBuilder)JedisClientConfiguration.builder();
//指定jedisPoolConifig來修改默認的連接池構造器(真麻煩,濫用設計模式!)
jpcb.poolConfig(jedisPoolConfig);
//通過構造器來構造jedis客戶端配置
JedisClientConfiguration jedisClientConfiguration = jpcb.build();
//單機配置 + 客戶端配置 = jedis連接工廠
return new JedisConnectionFactory(redisStandaloneConfiguration, jedisClientConfiguration);
}
}
RedisUtil
package org.feng.util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import java.time.Duration;
import java.util.Arrays;
import java.util.List;
/**
* RedisTemplate 的封裝類
*/
@Component
public class RedisUtil {
private final RedisTemplate<String, Object> redisTemplate;
@Autowired
public RedisUtil(RedisTemplate<String, Object> redisTemplate) {
this.redisTemplate = redisTemplate;
}
/**
* 判斷redis中是否有 key
* @param key 目標key
* @return 存在時返回true
*/
public boolean hasKey(String key){
Boolean hasKey = redisTemplate.hasKey(key);
if(hasKey != null){
return hasKey;
}
return false;
}
/**
* 存儲 set
* @param key 鍵
* @param value 值
* @return 存儲成功返回 true
*/
public boolean set(String key, Object value){
boolean flag = false;
try{
redisTemplate.opsForValue().set(key, value);
flag = true;
}catch (Exception e){
e.printStackTrace();
}
return flag;
}
/**
* 更新緩存
* @return 更新成功時返回 true
*/
public boolean getAndSet(String key, Object value){
boolean flag = false;
try {
redisTemplate.opsForValue().getAndSet(key, value);
flag = true;
} catch (Exception e){
e.printStackTrace();
}
return flag;
}
/**
* 刪除
* @param key
* @return
*/
public boolean delete(String key){
Boolean delete = false;
try{
delete = redisTemplate.delete(key);
} catch (Exception e){
e.printStackTrace();
}
return delete;
}
/**
* 存儲 set 並設置超時時長
* @param key 鍵
* @param value 值
* @param timeout 超時時間(超過該時間,redis 會自動刪除 key)
*/
public void setWithTime(String key, Object value, Duration timeout){
redisTemplate.opsForValue().set(key, value, timeout);
}
/**
* 獲取 key 對應的值
* @param key 鍵
* @return value
*/
public Object get(String key){
return redisTemplate.opsForValue().get(key);
}
/**
* 查詢多個結果:傳入多個key即可
* @param key 鍵
* @return 多個 value
*/
public List<Object> getList(String...key){
return redisTemplate.opsForValue().multiGet(Arrays.asList(key));
}
/**
* 獲取 redisTemplate 對象
* @return RedisTemplate 實例
*/
public RedisTemplate<String, Object> getRedisTemplate(){
return redisTemplate;
}
}
測試
package org.feng;
import org.feng.util.RedisUtil;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.util.Assert;
import java.io.Serializable;
import java.time.Duration;
import java.time.LocalDate;
@SpringBootTest
class SpringdataRedisApplicationTests {
@Autowired
private RedisUtil redisUtil;
@Test
void contextLoads() throws InterruptedException {
String key1 = "first";
String value1 = "1234567";
redisUtil.setWithTime(key1, value1, Duration.ofSeconds(3));
Assert.isTrue(redisUtil.hasKey(key1), key1 + " is must exist !");
// 自定義對象
Person value2 = new Person();
value2.setName("小鳳");
value2.setPassword("123445");
value2.setAge(10);
value2.setRegisterDay(LocalDate.of(2020,2, 21));
String key2 = "second";
redisUtil.set(key2, value2);
Assert.isTrue(redisUtil.hasKey(key2), key2 + " is must exist !");
// 輸出結果
redisUtil.getList(key1, key2).forEach(System.out::println);
// 3s 之後
Thread.sleep(3000);
Assert.isTrue(!redisUtil.hasKey(key1), key1 + " is must not exist !");
}
private static class Person implements Serializable {
private static final long serialVersionUID = 7813755876899907524L;
private String name;
private String password;
private Integer age;
private LocalDate registerDay;
public Person() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public LocalDate getRegisterDay() {
return registerDay;
}
public void setRegisterDay(LocalDate registerDay) {
this.registerDay = registerDay;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", password='" + password + '\'' +
", age=" + age +
", registerDay=" + registerDay +
'}';
}
}
}