redis 是一款開源的 Key-Value 數據庫,運行在內存中,由 ANSI C 編寫。企業開發通常採用 Redis 來實現緩存。同類的產品還有 memcache 、memcached 、MongoDB 等。
Redis支持豐富的數據結構,常用的有string、list、hash、set、sortset這幾種。學習這些數據結構是使用Redis的基礎!
首先還是得聲明一下,Redis的存儲是以key-value的形式的。Redis中的key一定是字符串,value可以是string、list、hash、set、sortset這幾種常用的。
一,Redis的下載和使用
目前官網只提供了linux版本的下載,我們想要使用windows版本的,只能在github上下載。
官網下載地址:http://redis.io/download
windows版本的Redis在github下載地址:https://github.com/MSOpenTech/redis/tags
爲了大家使用方便,博主在文章末的示例項目提供了redis的windows版本,裏面中win32位和win64位,供大家使用。
將下載的redis解壓到指定的目錄
主要有三個核心文件:
redis.windows.conf 配置文件,裏面是關於redis的一些配置,一般情況下,使用默認即可。
redis-cli.exe 啓動客戶端執行文件。
redis-server.exe啓動服務端執行文件
點擊redis-server.exe啓動redis服務
二,把Redis設置成windows下的服務
上面這種方式,雖然啓動了Redis服務,但是隻要一關閉cmd窗口,redis就會消失。所以要把redis設置成windows下的服務。
設置服務命令
redis-server --service-install redis.windows.conf --loglevel verbose
打開cmd,進入到redis的安裝目錄,執行上面的命令
我們win + R 鍵 打開運行窗口,輸入services.msc 查看windows服務
選中Redis服務,右鍵屬性
點擊服務狀態下的啓動按鈕這個服務就進行了開啓。如果你想讓這個服務在電腦開機的時候就啓動,在這個服務啓動之後,啓動類型保持默認自動就可以了,如果不想電腦開機時就啓動這個服務,可以設置啓動類型爲手動。博主在這裏選擇手動啓動類型,在需要這個服務時,再進行啓動,給電腦減輕負擔,嘿嘿,有沒有很機智!
這個服務被設置爲windows服務之後,還有一種方便的啓動與停止的方式。
以管理員身份打開cmd窗口,輸入 net start 服務名 即可啓動windows服務
輸入net stop 服務名 ,停止windows服務
這樣方式有沒有看起來逼格更高一點呢,小小嘚瑟一下😌
注意:
1.一定要以管理員的身份運行cmd窗口
2.服務名對應windows服務列表中的服務名稱
三, redis-cli.exe 啓動客戶端
言歸正傳,我們下面介紹使用redis-cli.exe客戶端可執行文件啓動redis客戶端來操作Redis
點擊redis安裝目錄下的redis-cli.exe啓動客戶端(服務端要保存開啓狀態)
redis的常用操作命令:
查看所有的key:keys*
設置值: set key的名稱 value值
獲取指定key的值: get key的名稱
四,Jedis 使用和圖形界面工具
Jedis 是 Redis 官方推出的一款面向 Java 的客戶端,提供了很多接口供 Java 語言調用。可以在 Redis 官網下載,當然還有一些開源愛好者提供的客戶端,如 Jredis、SRP 等等,推薦使用 Jedis。
Jedis網址: https://github.com/xetorthio/jedis
創建一個maven項目
主要引入的依賴:
Jedis : redis的java客戶端
Junit :方便進行代碼測試
引入的插件:
maven-compiler-plugin : 由於maven項目默認的編譯插件版本過低,需要這個編譯插件來設置編譯的版本
<dependencies>
<!-- Jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<!-- 單元測試 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
<build>
<plugins>
<!-- 編譯插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<encoding>utf-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
在引入編譯插件之後,項目會報錯,需要選中項目---->右鍵---->Maven---->Update Project 來更新項目
項目的編譯版本修改成功,變更爲1.7
準備工作就緒,接下來編寫redis java客戶端代碼,進行測試
@Test
public void redisTest() {
Jedis jedis = new Jedis("localhost"); //localhost 表示連接的是本地的Redis服務端
jedis.set("foo", "蘋果");
String value = jedis.get("foo");
System.out.println(value);
}
控制檯輸出
說明連接redis服務端連接成功,可以進行簡單的存值和取值
我們可以打開redis-cli.exe客戶端查看剛纔設置的key和value
當我們存取中文字符時,用redis-cli.exe客戶端查看發現對中文字符進行了轉碼,查看不很方便,這時,我們可以安裝redis 安裝圖形化界面客戶端來進行查看
這個安裝程序,在文章末的示例項目中提供。安裝步驟很簡單,不再演示。
安裝成功之後,按照下面操作即可
點擊創建的連接,裏面有16個db,默認使用的是db0
TTL 是 redis 的 key 有效時間,顯示-1 ,沒有設置 key 的有效期
一般通過java程序設置key的有效時間,不會使用圖形化界面來進行設置
設置key的有效週期
使用圖形化界面查看
如果我們要設置key的有效時間爲一天,那麼需要設置 60 * 60 * 24秒,這樣來換算,顯得不是很方便。當然,Jedis在很多方面的操作都是比較偏向底層的,使用起來不是很方便,而是在其上在封裝一層,作爲業務的使用。通常在開發中,使用Spring Data Redis來操作Redis。
五,Spring Data Redis 使用
Spring-data-redis 是 spring 大家族的一部分,提供了在 srping 應用中通過簡單的配置訪問 redis 服務,對 reids 底層開發包(Jedis, JRedis, and RJC)進行了高度封裝,RedisTemplate 提供了 redis 各種操作、異常處理及序列化,支持發佈訂閱,並對 spring 3.1 cache 進行了實現。
spring-data-redis 針對 jedis提供瞭如下功能:
1.連接池自動管理,提供了一個高度封裝的“RedisTemplate”類
2.針對jedis客戶端的大量api進行了歸類封裝,把同一類型的操作封裝成了Operation接口.支持redis中的五種數據類型的操作.
3.針對數據的"序列化與反序列化",提供了多種可以選擇的策略(RedisSerializer)
JdkSerializationRedisSerializer:當需要存儲java對象時使用.
StringRedisSerializer:當需要存儲string類型的字符串時使用.
JacksonJsonRedisSerializer:將對象序列化成json的格式存儲在redis中,需要jackson-json工具的支持
redisTemplate有兩個方法經常用到,一個是opsForXXX一個是boundXXXOps,XXX是value的類型
opsForXXX和boundXXXOps的區別
前者獲取到一個Opercation,但是沒有指定操作的key,可以在一個連接(事務)內操作多個key以及對應的value;後者會獲取到一個指定了key的operation,在一個連接內只操作這個key對應的value.
在實際開發過程中,選擇其中任意一種方式都可以。不過在示例項目中,這兩種方式都進行演示,大家根據喜好進行選擇。
==========================================================
在項目的pom.xml文件中引入的依賴:
spring-data-redis:對 reids 底層開發包(Jedis, JRedis, and RJC)進行了高度封裝,提供了一個高度封裝的“RedisTemplate”類來操作redis
spring-test:加載spring的配置文件,方便測試
<dependencies>
<!-- Jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<!-- 單元測試 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!--spring-data-redis -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.7.3.RELEASE</version>
</dependency>
<!--spring整合juint測試 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.3.8.RELEASE</version>
</dependency>
</dependencies>
spring的配置文件applicationContext-cache.xml配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache.xsd">
<!-- Jedis數據庫連接池 -->
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxIdle" value="300" />
<property name="maxWaitMillis" value="3000" />
<!-- 保證獲得的每一個Jedis實例都是可用的 -->
<property name="testOnBorrow" value="true" />
</bean>
<!-- redis連接工廠 跟配置數據庫連接池類似,需要配置JedisConnectionFactory來通過服務器或者連接池的方式獲取redis服務器的連接 -->
<bean id="connectionFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
p:host-name="localhost" p:port="6379" p:pool-config-ref="poolConfig"
p:database="0" />
<bean id="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
<bean id="jdkSerializationRedisSerializer" class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>
<!-- redis模板配置 spring-data-redis提供了一個基礎的泛型RedisTemplate封裝了基礎的crud操作-->
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="connectionFactory"/>
<!-- 序列化配置 可選配置-->
<property name="defaultSerializer" ref="stringRedisSerializer"/>
<property name="keySerializer" ref="stringRedisSerializer"/>
<property name="valueSerializer" ref="stringRedisSerializer"/>
</bean>
</beans>
編寫代碼演示opsForXXX的用法
方法一:opsForValue() 簡單 K-V 操作
/**
* 簡單key-value類型操作
*/
@Test
public void opsForValue() {
//設置key和value 並設置key的有效時間
redisTemplate.opsForValue().set("opsForValue", "小鬼",30,TimeUnit.SECONDS);
String value = (String) redisTemplate.opsForValue().get("opsForValue");
System.out.println(value);
}
/**
* 簡單key-value類型刪除操作
*/
@Test
public void delOpsForValue() {
redisTemplate.delete("opsForValue");
}
使用redis客戶端圖形化界面查看
方法二:opsForHash() 針對 map 類型的數據操作
這次不再向先前那樣,存放字符串,嘗試存放的數據是一個裝着User對象的List集合
/**
* 針對 map 類型的數據操作
*/
@Test
public void opsForHash() {
List<User> list = new ArrayList<>();
User u1 = new User();
u1.setId(1);
u1.setAge(1);
u1.setUsername("小張");
User u2 = new User();
u2.setId(2);
u2.setAge(2);
u2.setUsername("小王");
list.add(u1);
list.add(u2);
//向redis中存入一個list集合,list集合中存放的是user對象
//第一個參數 屬於大key 對應的值value是一個map 第二個參數是map的key 第三個參數是map的value
redisTemplate.opsForHash().put("opsForHash", "mapKey",list);
}
執行單元測試,出現了錯誤
java.lang.ClassCastException: java.util.ArrayList cannot be cast to java.lang.String
大概就是說類轉換異常,不能把ArrayList類轉成String類
出現的原因:
解決方式有兩種:
方式一:
1.修改屬性keySerializer爲hashKeySerializer 2.修改屬性valueSerializer爲hashValueSerializer 對應的ref="jdkSerializationRedisSerializer" <bean id="stringRedisSerializer"
class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
<bean id="jdkSerializationRedisSerializer"
class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>
<!-- redis模板配置 spring-data-redis提供了一個基礎的泛型RedisTemplate封裝了基礎的crud操作-->
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="connectionFactory"/>
<!-- 序列化配置 可選配置-->
<property name="defaultSerializer" ref="stringRedisSerializer"/>
<property name="hashKeySerializer" ref="stringRedisSerializer"/>
<property name="hashValueSerializer" ref="jdkSerializationRedisSerializer"/>
</bean>
2.,註釋掉序列化配置,使用默認的即可,推薦使用第二種。可以減少配置的同時,麻煩也少了
第二種實現的原理:
通過查看RedisTemplate
這個類的源碼,發現由於defaultSerializer
的序列化方式被初始化爲JdkSerializationRedisSerializer
,再通把defaultSerializer
的值賦值給keySerializer,valueSerializer,hashKeySerializer,hashValueSerializer
,所以他們的值都爲JdkSerializationRedisSerializer
。當向redis中存儲不是String字符串也是OK的。
修改完配置文件,進行代碼測試
/**
* 針對 map 類型的數據操作
*/
@Test
public void opsForHash() {
List<User> list = new ArrayList<>();
User u1 = new User();
u1.setId(1);
u1.setAge(1);
u1.setUsername("小張");
User u2 = new User();
u2.setId(2);
u2.setAge(2);
u2.setUsername("小王");
list.add(u1);
list.add(u2);
//向redis中存入一個list集合,list集合中存放的是user對象
//第一個參數 屬於大key 對應的值value是一個map 第二個參數是map的key 第三個參數是map的value
redisTemplate.opsForHash().put("opsForHash", "mapKey",list);
redisTemplate.opsForHash().put("opsForHash", "mapKey2",list);
redisTemplate.opsForHash().put("opsForHash", "mapKey3",list);
//獲取所有的小key
Set keys = redisTemplate.opsForHash().keys("opsForHash");
System.out.println("獲取所有的小key:"+keys);
//獲取所有的value
list = redisTemplate.opsForHash().values("opsForHash");
System.out.println("獲取所有的value: "+list);
//獲取某一個小key的value
list =(List<User>) redisTemplate.opsForHash().get("opsForHash", "mapKey");
System.out.println("獲取某一個小key的value: "+list);
}
控制檯成功輸出
刪除大key中的某一個小key 和 刪除整個大key
/**
* 針對 map 數據刪除操作
*/
@Test
public void delOpsForHash() {
//刪除大key中的某一個map
redisTemplate.opsForHash().delete("opsForHash", "mapKey");
//刪除大key
redisTemplate.delete("opsForHash");
}
===========================================================
剩下的三種方式使用大致相同,不做演示
opsForSet() set 類型數據操作
opsForList() 針對 list 類型的數據操作
opsForZSet() zset 類型數據操作
編寫代碼演示BoundXXXOpsTest的用法
方法一:boundValueOps() 簡單 K-V 操作
/**
* 簡單key-value類型操作
*/
@Test
public void boundValueOps() {
//設置key和value 並設置key的有效時間
redisTemplate.boundValueOps("boundValueOps").set("小鬼",30,TimeUnit.SECONDS);
String value = (String) redisTemplate.opsForValue().get("boundValueOps");
System.out.println(value);
}
/**
* 簡單key-value類型刪除操作
*/
@Test
public void delBoundValueOps() {
redisTemplate.delete("boundValueOps");
}
方法二:boundHashOps() 針對 map 類型的數據操作
/**
* 針對 map 類型的數據操作
*/
@Test
public void boundHashOps() {
List<User> list = new ArrayList<>();
User u1 = new User();
u1.setId(1);
u1.setAge(1);
u1.setUsername("小張");
User u2 = new User();
u2.setId(2);
u2.setAge(2);
u2.setUsername("小王");
list.add(u1);
list.add(u2);
//向redis中存入一個list集合,list集合中存放的是user對象
//第一個參數 屬於大key 對應的值value是一個map 第二個參數是map的key 第三個參數是map的value
redisTemplate.boundHashOps("boundHashOps").put("key1", list);
redisTemplate.boundHashOps("boundHashOps").put("key2", list);
redisTemplate.boundHashOps("boundHashOps").put("key3", list);
//獲取所有的小key
Set keys = redisTemplate.boundHashOps("boundHashOps").keys();
System.out.println("獲取所有的小key:"+keys);
//獲取所有的value
list = redisTemplate.boundHashOps("boundHashOps").values();
System.out.println("獲取所有的value: "+list);
//獲取某一個小key的value
list =(List<User>) redisTemplate.boundHashOps("boundHashOps").get("key1");
System.out.println("獲取某一個小key的value: "+list);
}
/**
* 針對 map 數據刪除操作
*/
@Test
public void delBoundHashOps() {
//刪除大key中的某一個map
redisTemplate.boundHashOps("boundHashOps").delete("key1");
//刪除大key
redisTemplate.delete("opsForHash");
}
剩下的三種方式使用大致相同,不做演示
boundSetOps() set 類型數據操作
boundListOps() 針對 list 類型的數據操作
boundZSetOps() zset 類型數據操作
==================================================================
以上就是有關Spring-data-redis對Redis的常用操作,後續會補充Redis搭建集羣的相關知識。
最後分享示例項目在碼雲的地址:https://gitee.com/xiaoguixiaogege/springdataredis