springboot 整合redis(lettuce)

springboot 整合redis(lettuce)

首先確保電腦上裝了redis。最好能用redisDesktop查看一下數據情況

redis是一款非常流行的Nosql數據庫。redis的功能非常強大,因為Nosql在查詢上的速度特別快。(在算法上的hash和數組查詢的差距)在web上常用作緩存(消息隊列等)。本文只介紹redis和springboot的集成,不介紹緩存部分下文將介紹緩存部分。目前流行的redis集成到java環境有jedis和lettuce。在之前版本中jedis可能更受青睞。但是在springboot2.0之後官方推薦的默認就是lettuce連接。因為jedis數據池雖然線程安全,但是佔用的資源較大,而lettuce基於netty和nio相關實現,性能更加強悍,佔用的資源也比較少,並且使用起來也不難。redis默認有16個分區(表),不配置情況默認用0個項目採取lettuce方式整合redis。lettuce性能更強點,喜歡jedis配合連接池也是線程安全的redis 默認五種基本類型:String,set,hash,zset(有序集合),listspring中redis 有StringRedisTemplate和RedisTemplate對於StringRedisTemplate,繼承RedisTemplate,只能存String類型的數據。不方面存對象,一般用的不是特別多(特定場景除外)。比較麻煩,存入的key和value都是字符型。對於RedisTemplate,默認是類型。如果不做配置,他會對key和value默認序列化成二進制文件看不懂。不利於觀察。一般重新配置redisTeamplate的一個bean。設置這個bean的key,value, 以及hashkey等等的序列化方式。一般是key序列化為string,value序列化為json,這樣,你就可以在存入對象時候它自動幫你序列化成字符或者json。方便觀察。對於整合redis你只需pom.xml引入相應依賴。在application.properties中填寫相應配置賬號密碼之類。在重寫RedisTemplate這個bean。配置他的序列化規則。
注意就是注入bean的時候名稱要和重寫的名一樣。因為這個對象是 spring幫你生成好的給你使用。而如果你隨便瞎起名字的話spring會根據原始重新生成對象。相當於引用未序列化的redisTemplate。更多的用法請百度。如果要存對象,那麼pojo一定要繼承序列化。否則無法存入redis。至於redis緩存,將在整合Springcache中介紹確保有無參構造方法和繼承序列化!

springboot官方的整合redis這麼說的

You can also register an arbitrary number of beans that implement LettuceClientConfigurationBuilderCustomizer for more advanced customizations. If you use Jedis, JedisClientConfigurationBuilderCustomizer is also available.If you add your own @Bean of any of the auto-configured types, it replaces the default (except in the case of RedisTemplate, when the exclusion is based on the bean name, redisTemplate, not its type). By default, if commons-pool2 is on the classpath, you get a pooled connection factory.

*

項目的目錄為

在這裡插入圖片描述

首先,在創建Springboot項目時候勾選redis選項或者在pom.xml中添加:

org.springframework.boot spring-boot-starter-data-redis org.apache.commons commons-pool2 在application.properties添加一下配置:

spring.redis.host=127.0.0.1 spring.redis.password= spring.redis.port= 6379 spring.redis.timeout=10000 spring.cache.type=redis # Redis默認情況下有16個分片,這裡配置具體使用的分片,默認是0 spring.redis.database=2 # 連接池最大連接數(使用負值表示沒有限制) 默認 8 spring.redis.lettuce.pool.max-active=8 # 連接池最大阻塞等待時間(使用負值表示沒有限制) 默認 -1 spring.redis.lettuce.pool.max-wait=-1 # 連接池中的最大空閒連接 默認 8 spring.redis.lettuce.pool.max-idle=8 # 連接池中的最小空閒連接 默認 0 spring.redis.lettuce.pool.min-idle=0 redis默認模板只能存儲,你也可以用但是每次都要轉成json字符串傳輸可能很麻煩,這樣你可以重寫一個模板程序自動加載,可以存 . 這是一個很重要的加載類,它聲明redis存儲類型:

import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; import java.io.Serializable; @Configuration @AutoConfigureAfter(RedisAutoConfiguration.class) public class RedisConfiguration { @Bean public RedisTemplate redisCacheTemplate(LettuceConnectionFactory redisConnectionFactory) { RedisTemplate template = new RedisTemplate<>(); GenericJackson2JsonRedisSerializer jackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer(); // 設置鍵(key)的序列化採用StringRedisSerializer。 template.setKeySerializer(new StringRedisSerializer()); // 設置值(value)的序列化採用jackson的序列化。 template.setValueSerializer(jackson2JsonRedisSerializer); template.setHashKeySerializer(new StringRedisSerializer()); template.setHashValueSerializer(jackson2JsonRedisSerializer); template.setConnectionFactory(redisConnectionFactory); return template; } } redisTest如下:user類:

package com.redis.pojo; import java.io.Serializable; public class user implements Serializable { //private static final Long private String name; private String password; private String sex; public user(){} @Override public String toString() { return "name:" name " password" password " sex" sex; } public user(String name, String password, String sex) { this.name=name; this.password=password; this.sex=sex; } 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 String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } }

controller

import com.redis.pojo.user; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class redisController { private final static Logger log= LoggerFactory.getLogger(redisController.class); /* 注入的名稱要和RedisConfiguration的名稱一致 否則注入的默認的redisTemplate 如果不喜歡序列化可以直接給config文件夾刪除,哈哈 */ @Autowired(required = false) RedisTemplate redisCacheTemplate; //如果RedisTemplate redisTemplate就相當沒配置序列化等 @Autowired(required = false) StringRedisTemplate stringRedisTemplate; @Autowired(required = false) RedisTemplate redisTemplate; @GetMapping("test1")//StringRedistemplate 存String public String test1() { stringRedisTemplate.opsForValue().set("test1","hello賽賽");//再desttop中可以看到為中文串 stringRedisTemplate.opsForValue().set("redis:test1","hello賽賽");//再desttop中可以看到為中文串 redisTemplate.opsForValue().set("test1","hello賽賽");//再desttop中可以看到為二進制數字亂起八糟 String val1=stringRedisTemplate.opsForValue().get("test1"); //String va2=(String) redisCacheTemplate.opsForValue().get("test1");//不註釋會報異常,因為Stingxxtemplate就是String沒有序列化過。反序列化會報異常 log.info(val1+" "); return val1+" "; } @GetMapping("test2")//Redistemplate 存String public String test2() { redisCacheTemplate.opsForValue().set("bigsai222","hello賽賽2"); String val1=stringRedisTemplate.opsForValue().get("bigsai222");//為 "hello賽賽2" 多個引號 String va2=(String) redisCacheTemplate.opsForValue().get("bigsai222");//為 hello賽賽2 沒有引號因為json反序列化 log.info(val1+" "+va2); return val1+" "+va2; } @GetMapping("test3") public user test3() { user user=new user("大佬","點個star謝謝!","man"); redisCacheTemplate.opsForValue().set("user",user); user value=(user) redisCacheTemplate.opsForValue().get("user"); log.info(redisCacheTemplate.hasKey("user")+"");//判斷是否有鍵值對 return value; } }

test類

package com.redis; import com.redis.pojo.user; import org.junit.Test; import org.junit.runner.RunWith; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.test.context.junit4.SpringRunner; import java.io.Serializable; @RunWith(SpringRunner.class) @SpringBootTest public class RedisApplicationTests { private final static Logger log= LoggerFactory.getLogger(RedisApplicationTests.class); @Autowired(required = false) RedisTemplate redisCacheTemplate; @Autowired(required = false) RedisTemplate redisTemplate; @Test public void contextLoads() { } @Test public void test1() { redisCacheTemplate.opsForValue().set("hello","heoolo"); log.warn((String) redisCacheTemplate.opsForValue().get("hello")); } @Test public void test2() { user usr=new user("66","賽格","man"); redisCacheTemplate.opsForValue().set("bigsai",usr); user user2=(user) redisCacheTemplate.opsForValue().get("bigsai"); log.warn(user2.toString()); } @Test public void test3() { user usr=new user("66","賽格","man"); redisTemplate.opsForValue().set("bigsai33",usr); user user2=(user) redisTemplate.opsForValue().get("bigsai33"); log.warn(user2.toString()); } } 訪問test1,你可以大概看到對象測試情況:

在這裡插入圖片描述還有其他的test和controller可以自行訪問體驗其中差異。最好用redis的客戶端工具觀察。如果不想配置序列化直接使用即可,不需要redis配置類(不利於觀察不推薦)!你可以看到已經成功了,但是你可能會發現redis存儲對象的方式是json格式。其實redis本身不支持object類型對象,我們通過中間json達到存儲object效果。你可能還會有疑問,為啥redis模板不是而是。這就涉及到java傳輸信息時候的序列化和接收的反序列化。他可以完美的序列化,反序列化。關於序列化的意義和內容更多可以百度,在聲明User類的時候,它繼承了序列化接口,那麼可以直接這樣寫。這個思想可以瞭解下java面向對象繼承的向上繼承和向下繼承。另外,redis還可以操作一些其他類型>下列的就是Redis其它類型所對應的操作方式:opsForValue: 對應 String(字符串)opsForZSet: 對應 ZSet(有序集合)opsForHash: 對應 Hash(哈希)opsForList: 對應 List(列表)opsForSet: 對應 Set(集合)opsForGeo: 對應 GEO(地理位置)

那麼springboot和mybatis,redis已經整合完畢了。你可以在項目中存取一些適合key-value的數值,並且使用起來相比mysql也要方便一些。

項目github地址

如果描述錯誤還請大佬指正

公眾號:bigsai

頭條號:一直碼農一直爽