SpringBoot整合Redis使用RedisTemplate和StringRedisTemplate
Spring Boot Data(數(shù)據(jù)) Redis 中提供了RedisTemplate和StringRedisTemplate,其中StringRedisTemplate是RedisTemplate的子類,兩個方法基本一致,不同之處主要體現(xiàn)在操作的數(shù)據(jù)類型不同,RedisTemplate中的兩個泛型都是Object,意味著存儲的key和value都可以是一個對象,而StringRedisTemplate的兩個泛型都是String,意味著StringRedisTemplate的key和value都只能是字符串。
注意:
使用RedisTemplate默認是將對象序列化到Redis中,所以放入的對象必須實現(xiàn)對象序列化接口
springboot 2.x后 ,原來使用的 Jedis 被 lettuce 替換。
jedis:采用的直連,多個線程操作的話,是不安全的。如果要避免不安全,使用jedis pool連接池!更像BIO模式
lettuce:采用netty,實例可以在多個線程中共享,不存在線程不安全的情況!可以減少線程數(shù)據(jù)了,更像NIO模式
1.環(huán)境準備
1.1.引入依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
1.2.配置application.propertie
# springboot所有的配置類都有一個自動配置類, xxxAutoConfiguration # 自動配置類都會綁定一個properties 的配置文件,xxxProperties ??????? spring.redis.host=127.0.0.1 #localhost spring.redis.port=6379 spring.redis.database=0
源碼分析:
@Bean
@ConditionalOnMissingBean(name = "redisTemplate")
// 可以自己定義一個redisTemplate來替換這個默認的!
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
// 默認的 RedisTemplate 沒有過多的設(shè)置,redis 對象都是需要序列化!
// 兩個泛型都是 Object, Object 的類型,我們后使用需要強制轉(zhuǎn)換 <String, Object>
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
@Bean
@ConditionalOnMissingBean
//由于String是redis中最常使用的類型,所以單獨提一個bean!
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
StringRedisTemplate template = new StringRedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
1.3. 連接測試
可以看一下第二節(jié)
redisTemplate 操作不同的數(shù)據(jù)類型,api和我們的指令是一樣的
opsForValue 操作字符串 類似String
opsForList 操作List 類似List
- opsForSet
- opsForHash
- opsForZSet
- opsForGeo
- opsForHyperLogLog
除了進本的操作,我們常用的方法都可以直接通過redisTemplate操作,比如事務(wù),和基本的CRUD
獲取redis的連接對象
RedisConnection connection = redisTemplate.getConnectionFactory().getConnection(); connection.flushDb(); connection.flushAll();
2.使用StringRedisTemplate和RedisTemplate
@Autowired
private StringRedisTemplate stringRedisTemplate; //對字符串支持比較友好,不能存儲對象
@Autowired
private RedisTemplate redisTemplate; //存儲對象
@Test
public void testRedisTemplate(){
System.out.println(redisTemplate);
//設(shè)置redistemplate值使用對象序列化策略
redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());//指定值使用對象序列化
//redisTemplate.opsForValue().set("user",new User("1","qinyu",99,new Date()));
User user = (User) redisTemplate.opsForValue().get("user");
System.out.println(user);
//Set keys = redisTemplate.keys("*");
//keys.forEach(key -> System.out.println(key));
/*Object name = redisTemplate.opsForValue().get("name");
System.out.println(name);*/
//Object qinyu= redisTemplate.opsForValue().get("qinyu");
//System.out.println(qinyu);
/*redisTemplate.opsForValue().set("name","xxxx");
Object name = redisTemplate.opsForValue().get("name");
System.out.println(name);*/
/*redisTemplate.opsForList().leftPushAll("lists","xxxx","1111");
List lists = redisTemplate.opsForList().range("lists", 0, -1);
lists.forEach(list-> System.out.println(list));*/
}
/*key的綁定操作 如果日后對某一個key的操作及其頻繁,可以將這個key綁定到對應(yīng)redistemplate中,日后基于綁定操作都是操作這個key
boundValueOps 用來對String值綁定key
boundListOps 用來對List值綁定key
boundSetOps 用來對Set值綁定key
boundZsetOps 用來對Zset值綁定key
boundHashOps 用來對Hash值綁定key
*/
@Test
public void testBoundKey(){
BoundValueOperations<String, String> nameValueOperations = stringRedisTemplate.boundValueOps("name");
nameValueOperations.set("1");
//yuew
nameValueOperations.set("2");
String s = nameValueOperations.get();
System.out.println(s);
}
//hash相關(guān)操作 opsForHash
@Test
public void testHash(){
stringRedisTemplate.opsForHash().put("maps","name","qinyu");
Object o = stringRedisTemplate.opsForHash().get("maps", "name");
System.out.println(o);
}
//zset相關(guān)操作 opsForZSet
@Test
public void testZSet(){
stringRedisTemplate.opsForZSet().add("zsets","qinyu",10);
Set<String> zsets = stringRedisTemplate.opsForZSet().range("zsets", 0, -1);
zsets.forEach(value-> System.out.println(value));
}
//set相關(guān)操作 opsForSet
@Test
public void testSet(){
stringRedisTemplate.opsForSet().add("sets","xiaosan","xiaosi","xiaowu");
Set<String> sets = stringRedisTemplate.opsForSet().members("sets");
sets.forEach(value-> System.out.println(value));
}
//list相關(guān)的操作opsForList
@Test
public void testList(){
// stringRedisTemplate.opsForList().leftPushAll("lists","張三","李四","王五");
List<String> lists = stringRedisTemplate.opsForList().range("lists", 0, -1);
lists.forEach(key -> System.out.println(key));
}
//String相關(guān)的操作 opsForValue
@Test
public void testString(){
//stringRedisTemplate.opsForValue().set("166","好同學");
String s = stringRedisTemplate.opsForValue().get("166");
System.out.println(s);
Long size = stringRedisTemplate.opsForValue().size("166");
System.out.println(size);
}
//key相關(guān)的操作
@Test
public void test(){
Set<String> keys = stringRedisTemplate.keys("*");//查看所有key
Boolean name = stringRedisTemplate.hasKey("name");//判斷某個key是否存在
stringRedisTemplate.delete("age");//根據(jù)指定key刪除
stringRedisTemplate.rename("","");//修改key的名稱
stringRedisTemplate.expire("key",10, TimeUnit.HOURS);
//設(shè)置key超時時間 參數(shù)1:設(shè)置key名 參數(shù)2:時間 參數(shù)3:時間的單位
stringRedisTemplate.move("",1);//移動key
}
3.自定義RedisTemplate
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.StringRedisSerializer;
@Configuration
public class RedisConfig {
// 自己定義一個 RedisTemplate
@Bean
@SuppressWarnings("all")
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
// 我們?yōu)榱俗约洪_發(fā)方便,一般直接使用 <String, Object>
RedisTemplate<String, Object> template = new RedisTemplate<String,Object>();
template.setConnectionFactory(factory);
// Json序列化配置
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);
// String 的序列化
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// key采用String的序列化方式
template.setKeySerializer(stringRedisSerializer);
// hash的key也采用String的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
// value序列化方式采用jackson
template.setValueSerializer(jackson2JsonRedisSerializer);
// hash的value序列化方式采用jackson
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
}4.配置文件
啟動的時候,就通過配置文件來啟動!
單位 容量單位不區(qū)分大小寫,G和GB有區(qū)別
1.配置文件 unit單位 對大小寫不敏感!
2.包含 可以使用 include 組合多個配置問題
例如:include /path/to/local.conf
3.網(wǎng)絡(luò)
bind 127.0.0.1 # 綁定的ip protected-mode yes # 保護模式 port 6379 # 端口設(shè)置
4.通用 GENERAL
daemonize yes # 以守護進程的方式運行(就是后臺運行),默認是 no,我們需要自己開啟為yes! pidfile /var/run/redis_6379.pid # 如果以后臺的方式運行,我們就需要指定一個 pid 文件! # 日志 # Specify the server verbosity level. # This can be one of: redis 是內(nèi)存數(shù)據(jù)庫,如果沒有持久化,那么數(shù)據(jù)斷電及失! REPLICATION 復制,我們后面講解主從復制的,時候再進行講解 SECURITY 安全 可以在這里設(shè)置redis的密碼,默認是沒有密碼! # debug (a lot of information, useful for development/testing) # verbose (many rarely useful info, but not a mess like the debug level) # notice (moderately verbose, what you want in production probably) 生產(chǎn)環(huán)境 # warning (only very important / critical messages are logged) loglevel notice logfile "" # 日志的文件位置名 databases 16 # 數(shù)據(jù)庫的數(shù)量,默認是 16 個數(shù)據(jù)庫 always-show-logo yes # 是否總是顯示LOGO
5.快照
持久化, 在規(guī)定的時間內(nèi),執(zhí)行了多少次操作,則會持久化到文件 .rdb. aof
redis 是內(nèi)存數(shù)據(jù)庫,如果沒有持久化,那么數(shù)據(jù)斷電及失!
# 如果900s內(nèi),如果至少有一個1 key進行了修改,我們及進行持久化操作 save 900 1 # 如果300s內(nèi),如果至少10 key進行了修改,我們及進行持久化操作 save 300 10 # 如果60s內(nèi),如果至少10000 key進行了修改,我們及進行持久化操作 save 60 10000 # 之后學習持久化,會自己定義這個測試! stop-writes-on-bgsave-error yes # 持久化如果出錯,是否還需要繼續(xù)工作! 默認保存出錯的話停止操作 rdbcompression yes # 是否壓縮 rdb 文件,需要消耗一些cpu資源! rdbchecksum yes # 保存rdb文件的時候,進行錯誤的檢查校驗! dir ./ # rdb 文件保存的目錄!
6.SECURITY 安全
可以在這里設(shè)置redis的密碼,默認是沒有密碼!
127.0.0.1:6379> ping PONG 127.0.0.1:6379> config get requirepass # 獲取redis的密碼 1) "requirepass" 2) "" 127.0.0.1:6379> config set requirepass "123456" # 設(shè)置redis的密碼 OK 127.0.0.1:6379> config get requirepass # 發(fā)現(xiàn)所有的命令都沒有權(quán)限了 (error) NOAUTH Authentication required. 127.0.0.1:6379> ping (error) NOAUTH Authentication required. 127.0.0.1:6379> auth 123456 # 使用密碼進行登錄! OK 127.0.0.1:6379> config get requirepass 1) "requirepass" 2) "123456"
7.限制 CLIENTS
maxclients 10000 # 設(shè)置能連接上redis的最大客戶端的數(shù)量 maxmemory <bytes> # redis 配置最大的內(nèi)存容量 maxmemory-policy noeviction # 內(nèi)存到達上限之后的處理策略 # redis 中的默認的過期策略是 volatile-lru 。 1、volatile-lru:只對設(shè)置了過期時間的key進行LRU(默認值) 2、allkeys-lru : 刪除lru算法的key 3、volatile-random:隨機刪除即將過期key 4、allkeys-random:隨機刪除 5、volatile-ttl : 刪除即將過期的 6、noeviction : 永不過期,返回錯誤 ------------------------------------------------ # 設(shè)置方式 config set maxmemory-policy volatile-lru
8.APPEND ONLY 模式 aof配置
appendonly no # 默認是不開啟aof模式的,默認是使用rdb方式持久化的,在大部分所有的情況下, rdb完全夠用! appendfilename "appendonly.aof" # 持久化的文件的名字 # appendfsync always # 每次修改都會 sync。消耗性能 appendfsync everysec # 每秒執(zhí)行一次 sync,可能會丟失這1s的數(shù)據(jù)! # appendfsync no # 不執(zhí)行 sync,這個時候操作系統(tǒng)自己同步數(shù)據(jù),速度最快!
9.bgsave
bgsave 是異步進行,進行持久化的時候,redis 還可以將繼續(xù)響應(yīng)客戶端請求 ;
bgsave和save對比
| 命令 | save | bgsave |
|---|---|---|
| IO類型 | 同步 | 異步 |
| 阻塞? | 是 | 是(阻塞發(fā)生在fock(),通常非??欤?/td> |
| 復雜度 | O(n) | O(n) |
| 優(yōu)點 | 不會消耗額外的內(nèi)存 | 不阻塞客戶端命令 |
| 缺點 | 阻塞客戶端命令 | 需要fock子進程,消耗內(nèi)存 |
5.自定義工具類
可以參考下面的鏈接
SpringBoot整合Redis及Redis工具類撰寫實例
到此這篇關(guān)于SpringBoot整合Redis使用RedisTemplate和StringRedisTemplate的文章就介紹到這了,更多相關(guān)SpringBoot整合Redis內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 在SpringBoot中注入RedisTemplate實例異常的解決方案
- SpringBoot整合Redis使用@Cacheable和RedisTemplate
- SpringBoot整合RedisTemplate實現(xiàn)緩存信息監(jiān)控的步驟
- 詳解SpringBoot使用RedisTemplate操作Redis的5種數(shù)據(jù)類型
- springboot使用redisRepository和redistemplate操作redis的過程解析
- SpringBoot混合使用StringRedisTemplate和RedisTemplate的坑及解決
- SpringBoot集成RedisTemplate的實現(xiàn)示例
相關(guān)文章
java整數(shù)(秒數(shù))轉(zhuǎn)換為時分秒格式的示例
這篇文章主要介紹了java整數(shù)(秒數(shù))轉(zhuǎn)換為時分秒格式的示例,需要的朋友可以參考下2014-04-04
解析SpringSecurity自定義登錄驗證成功與失敗的結(jié)果處理問題
這篇文章主要介紹了SpringSecurity系列之自定義登錄驗證成功與失敗的結(jié)果處理問題,本文通過實例給大家講解的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2019-11-11
詳解SpringBoot實現(xiàn)ApplicationEvent事件的監(jiān)聽與發(fā)布
這篇文章主要為大家詳細介紹了SpringBoot如何實現(xiàn)ApplicationEvent事件的監(jiān)聽與發(fā)布,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下2023-03-03
Java數(shù)據(jù)結(jié)構(gòu)篇之實現(xiàn)二叉搜索樹的核心方法
二叉搜索樹是一種常用的數(shù)據(jù)結(jié)構(gòu),它是一棵二叉樹,且每個節(jié)點的值都大于其左子樹中任何節(jié)點的值,而小于其右子樹中任何節(jié)點的值,這篇文章主要給大家介紹了關(guān)于Java數(shù)據(jù)結(jié)構(gòu)篇之實現(xiàn)二叉搜索樹的核心方法,需要的朋友可以參考下2023-12-12
java返回前端實體類json數(shù)據(jù)時忽略某個屬性方法
這篇文章主要給大家介紹了關(guān)于java返回前端實體類json數(shù)據(jù)時忽略某個屬性的相關(guān)資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下2023-08-08

