Spring+Redis整合
一:目錄
- redis的安裝和啟動
- jedis的使用
- Hello World
- JedisPool的使用
- Spring整合
二:Redis下載、安裝和啟動
2、啟動Redis服務
使用終端切換到redis的目錄下,然後 使用命令啟動 redis-server.exe redis.windows.conf
3、啟動客戶端
使用終端切換到redis的目錄下,然後 使用命令啟動 redis-cli.exe
三:jedis的使用
1、在pom.xml 中引入spring(需要用到spring-test來測試)和jedis相關的依賴
<properties >
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>4.2.3.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId >
<version>4.10</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
<!-- springframework -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
</dependencies>
2、測試Jedis相關的方法
這裡只是列舉出jedis常用的一些方法,jedis的方法名和redis的命令是一樣的,瞭解了命令就自然知道jedis中相關的方法了,這裡並不介紹redis中的每個命令
SpringTestCase
package com.mengdee.manager.redis;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@ContextConfiguration(locations = {"classpath:conf/spring/spring-base.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
public class SpringTestCase extends AbstractJUnit4SpringContextTests{
}
JedisTest
package com.mengdee.manager.redis;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import redis.clients.jedis.Jedis;
public class JedisTest extends SpringTestCase{
private Jedis jedis;
@Before
public void setup(){
jedis = new Jedis("127.0.0.1", 6379);
}
/**
* redis 字串string
*
* 常用操作:新增鍵值對 、獲取鍵對應的值、刪除鍵、批量新增鍵值對、對數字型的值+1或者-1
*/
@Test
public void testString() {
//-----新增資料----------
String key = "name";
jedis.set(key,"mengdee");
System.out.println(jedis.get(key));
jedis.append(key, " is good");
System.out.println(jedis.get(key));
jedis.del(key);
System.out.println(jedis.get(key));
// 批量新增鍵值對,注意值都是字串型別,注意這裡是一次性新增三個鍵值對,他們的關係是並列關係(即使三個鍵值對而不是一個鍵值對的值是三個值)
jedis.mset("name","mengdee","age","23","nickname","mengday");
jedis.incr("age"); //進行加1操作
System.out.println(jedis.get(key) + "-" + jedis.get("age") + "-" + jedis.get("nickname"));
}
/**
* redis map
* map 包含多個鍵值對,通常儲存Java中的物件使用map資料型別儲存
*/
@Test
public void testMap() {
//-----新增資料----------
Map<String, String> userMap = new HashMap<String, String>();
userMap.put("id", "1");
userMap.put("username", "mengdee");
userMap.put("age", "20");
String key = "user:1";
jedis.hmset(key, userMap);
// 一次獲取多個欄位的值
List<String> values = jedis.hmget(key, "id", "username", "age");
System.out.println(values);
// 通常使用hgetAll獲取到的Map轉換成Java中的物件
Map<String, String> userMap2 = jedis.hgetAll(key);
Set<Entry<String, String>> entrySet = userMap2.entrySet();
for (Entry<String, String> entry : entrySet) {
System.out.println(entry.getKey() + ":" + entry.getValue());
}
System.out.println(jedis.hmget(key, "age"));
System.out.println(jedis.hlen(key));
System.out.println(jedis.exists(key));
System.out.println(jedis.hkeys(key));
System.out.println(jedis.hvals(key));
jedis.hdel(key,"age");
}
/**
* jedis list(一般儲存像Java中的陣列或者List這樣的資料型別)
*/
@Test
public void testList(){
//開始前,先移除所有的內容
String key = "java";
jedis.del(key);
jedis.lpush(key, "gradle");
jedis.lpush(key, "springmvc");
jedis.lpush(key, "mybatis");
jedis.rpush(key, "spring boot");
System.out.println(jedis.lrange(key, 0, -1));
jedis.del(key);
jedis.rpush(key, "spring");
jedis.rpush(key, "struts");
jedis.rpush(key, "hibernate");
System.out.println(jedis.lrange(key, 0, -1));
}
/**
* jedis set
*
* 注意set操作是無須的
*/
@Test
public void testSet(){
//新增
String key = "users";
jedis.sadd(key,"zhangsan");
jedis.sadd(key,"lisi");
jedis.sadd(key,"mengdee");
jedis.sadd(key,"mengday");
jedis.sadd(key,"X");
jedis.srem(key,"X");
System.out.println(jedis.smembers(key));
System.out.println(jedis.sismember(key, "mengdee"));
System.out.println(jedis.srandmember(key));
System.out.println(jedis.scard(key));
}
}
3、JedisPool的使用
上面示例是沒有使用執行緒池的,在實際開發中肯定要使用執行緒池,要不然每次都要建立連線,下面只是簡單的實現方式,demo版,不能實際在專案中使用,在專案中實際使用還需要使用更優的實現
package com.mengdee.manager.utils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
public final class RedisUtil {
//Redis伺服器IP
private static String ADDR = "127.0.0.1";
//Redis的埠號
private static int PORT = 6379;
//訪問密碼
private static String AUTH = "admin";
//控制一個pool最多有多少個狀態為idle(空閒的)的jedis例項,預設值也是8。
private static int MAX_IDLE = 200;
private static int TIMEOUT = 10000;
//在borrow一個jedis例項時,是否提前進行validate操作;如果為true,則得到的jedis例項均是可用的;
private static boolean TEST_ON_BORROW = true;
private static JedisPool jedisPool = null;
/**
* 初始化Redis連線池
*/
static {
try {
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxIdle(MAX_IDLE);
config.setTestOnBorrow(TEST_ON_BORROW);
jedisPool = new JedisPool(config, ADDR, PORT, TIMEOUT, AUTH);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 獲取Jedis例項
* @return
*/
public synchronized static Jedis getJedis() {
try {
if (jedisPool != null) {
Jedis resource = jedisPool.getResource();
return resource;
} else {
return null;
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 釋放jedis資源
* @param jedis
*/
public static void returnResource(final Jedis jedis) {
if (jedis != null) {
jedisPool.returnResource(jedis);
}
}
}
使用JedisUtil獲取Jedis物件,操作快取
@Test
public void testRedisPool() {
JedisUtil.getJedis().set("newname", "中文測試");
System.out.println(RedisUtil.getJedis().get("newname"));
}
第二部分:Spring整合
開發中可以單獨使用Jedis中相關的方法操作快取,也可以使用spring提供的相關的註解
1、 在pom.xml中引入相關依賴
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>4.2.3.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
<!-- springframework -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.8.1.RELEASE</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
</dependencies>
2、在src/main/resources/conf/settings/application.properties下配置redis相關配置
redis.master.ip=localhost
redis.master.port=6379
redis.pool.maxActive=1024
redis.pool.maxIdle=200
redis.pool.maxWait=1000
redis.pool.testOnBorrow=true
redis.pool.testOnReturn=true
3、在src/main/resources/conf/spring 下配置spring-base.xml和spring-redis.xml
spring-base.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:util="http://www.springframework.org/schema/util"
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/util http://www.springframework.org/schema/util/spring-util.xsd">
<!-- 載入配置檔案資料庫連線檔案 -->
<context:property-placeholder location="classpath:conf/settings/*.properties" />
<context:component-scan base-package="com.mengdee.**.dao,com.mengdee.**.service"/>
</beans>
spring-redis.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:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
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/cache
http://www.springframework.org/schema/cache/spring-cache.xsd">
<!-- 以前專案中的配置,注意需要新增Spring Data Redis等jar包 -->
<description>redis配置</description>
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxIdle" value="${redis.pool.maxIdle}"/>
<property name="maxTotal" value="${redis.pool.maxActive}"/>
<property name="maxWaitMillis" value="${redis.pool.maxWait}"/>
<property name="testOnBorrow" value="${redis.pool.testOnBorrow}"/>
<property name="testOnReturn" value="${redis.pool.testOnReturn}"/>
</bean>
<!-- JedisConnectionFactory -->
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="hostName" value="${redis.master.ip}"/>
<property name="port" value="${redis.master.port}"/>
<property name="poolConfig" ref="jedisPoolConfig"/>
</bean>
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"
p:connectionFactory-ref="jedisConnectionFactory">
<property name="keySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer"></bean>
</property>
<property name="valueSerializer">
<bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>
</property>
<property name="hashKeySerializer">
<bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>
</property>
<property name="hashValueSerializer">
<bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>
</property>
</bean>
<!--spring cache-->
<bean id="cacheManager" class="org.springframework.data.redis.cache.RedisCacheManager"
c:redisOperations-ref="redisTemplate">
<!-- 預設快取10分鐘 -->
<property name="defaultExpiration" value="600"/>
<property name="usePrefix" value="true"/>
<!-- cacheName 快取超時配置,半小時,一小時,一天 -->
<property name="expires">
<map key-type="java.lang.String" value-type="java.lang.Long">
<entry key="halfHour" value="1800"/>
<entry key="hour" value="3600"/>
<entry key="oneDay" value="86400"/>
<!-- shiro cache keys -->
<entry key="authorizationCache" value="1800"/>
<entry key="authenticationCache" value="1800"/>
<entry key="activeSessionCache" value="1800"/>
</map>
</property>
</bean>
<!-- cache註解,和spring-ehcache.xml中的只能使用一個 -->
<cache:annotation-driven cache-manager="cacheManager" proxy-target-class="true"/>
</beans>
4、Service 類
User
package com.mengdee.manager.entity;
import java.io.Serializable;
// 一定要實現Serializable,否則報錯
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String username;
private int age;
public User() {
super();
}
public User(Long id, String username, int age) {
super();
this.id = id;
this.username = username;
this.age = age;
}
@Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", age=" + age + "]";
}
// getter && setter
}
UserService
package com.mengdee.manager.service;
import com.mengdee.manager.entity.User;
public interface UserService {
public User getUserInfo(String username);
public void deleteUser(String username);
public User updateUser(User user);
}
UserServiceImpl
package com.mengdee.manager.service;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import com.mengdee.manager.entity.User;
@Service
public class UserServiceImpl implements UserService {
@Cacheable("users")
@Override
public User getUserInfo(String username) {
System.out.println("從資料庫中查詢使用者資訊。。。");
long id = (int)((Math.random()*9+1)*100000);
return new User(id, username, 20);
}
@CacheEvict("users")
@Override
public void deleteUser(String username) {
System.out.println("刪除使用者:"+username);
}
// 使用@CachePut比許返回要快取的物件,使用value作為鍵的字首(users),使用冒號作為分隔符(:),使用key的值追加到前面的組合,如"users:mengdee"
// 方法的返回值作為鍵值對的值快取起來,如果方法沒有返回值,那麼就相當於沒有更新快取
@CachePut(value="users", key="#user.getUsername()")
@Override
public User updateUser(User user) {
System.out.println("更新使用者");
return user;
}
}
5、測試
UserServiceTest
package com.mengdee.manager.redis;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import com.mengdee.manager.service.UserService;
public class UserServiceTest extends SpringTestCase{
@Autowired
private UserService userService;
@Test
public void testGetUserInfo(){
String username = "mengdee";
// 第一次執行了方法體
userService.getUserInfo(username);
// 第二次沒有執行方法體,直接從快取中獲取的
User userInfo = userService.getUserInfo(username);
System.out.println(userInfo); // User [id=565857, username=mengdee, age=20]
}
@Test
public void testDeleteUser(){
String username = "mengdee";
User userInfo = userService.getUserInfo(username);
System.out.println(userInfo);
userService.getUserInfo(username);
userService.deleteUser(username);
}
@Test
public void testUpdateUser(){
String username = "mengdee";
User userInfo = userService.getUserInfo(username);
System.out.println(userInfo);
userInfo.setAge(200);
userInfo.setId(10L);
userService.updateUser(userInfo);
User userInfo2 = userService.getUserInfo(username);
System.out.println(userInfo2);
}
}
使用redis-cli可以看到User物件快取的鍵是“users:mengdee”, 從中可以看出key的預設規則是@Cacheable中的value值跟冒號分隔,然後跟引數的實際值
注意
1、注意配置key的失效時間,既可以野資料的存在,也最大化利用記憶體,一般不要失效時間配置為永久
2、在使用redis的時候,對於鍵的命名規則非常重要,常用的做法是實體名字串跟冒號跟ID值,如“user:1”, “user:2”, 或者其他命名規則在使用Spring的 @Cacheable 的時候更要注意,因為當兩個方法的key相同時,兩個方法的返回值會相互覆蓋,例如以下兩個方法
@Cacheable("user")
User getUser(String id);
@Cacheable("user")
User getUserDetail(String id);
當執行第一個方法後換成user物件,再執行第二個方法還會換成user物件,因為這兩個方法的key最終生成的是完全一樣的,所以第二個方法其實會更新快取,這兩個方法返回雖然都是User物件,很可能返回user物件的欄位是不同的,這樣在使用user物件時很可能拿不到值,解決方法就是key的生成規則一定不能一樣,可以在key的生成規則中加入方法名作為區分,當然這不是一個很好的方式,因為方法名往往是比較長的,key越長越佔記憶體,key應該儘可能的簡短來節省記憶體
相關推薦
eclipse spring redis 整合-配置
wait 版本 ace name 合取 instance wid cati 17. 花了一天時間折騰redis的配置 用到的jar spring 3.1.1 aopalliance-1.0.jar commons-pool2-2.3.jar jedis-2.7.2
ssm中加入redis,spring -redis整合,簡單,認識redis
1匯入spring和redis的jar包,當然推薦用maven。開啟服務 2.application.xml中配置 定義執行緒池 <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
spring + redis 整合
1.新增pom依賴 <properties> <spring.version>5.0.8.RELEASE</spring.version> <redis.version>2.9.
Spring+Redis整合以及異常 Could not resolve placeholder解決
spring+Redis 概述 本文主要為了整合spring和redis,以及記錄解決中間遇到的問題。 什麼是redis? Redis是一個開源的使用ANSI C語言編寫、支援網路、可基於記憶體亦可持久化的日誌型、Key-Value資料庫,並提供多種語言
java程式碼中操作Redis:單機redis、叢集redis(spring+redis整合)
一、準備 關於redis的一些安裝,可以檢視我的幾篇文章自行安裝:Redis目錄。匯入java的Redis客戶端依賴包Jedis:<dependency> <groupId>redis.clients</groupId
spring+redis整合,策略設計,靈活配置,支援單機和叢集
spring+redis整合,策略設計,支援單機和叢集 前言 單JVM保證併發資料安全 1.執行緒同步鎖,synchronized(this)或者Lock介面 2.資料表增加版本號欄位,update where條件後面跟上版本號.這樣就只會更新一次 3.
Spring+Redis整合
一:目錄 redis的安裝和啟動 jedis的使用 Hello World JedisPool的使用 Spring整合 二:Redis下載、安裝和啟動 2、啟動Redis服務 使用終端切換到redis的目錄下,然後 使用命令啟動 red
jedis,spring-redis-data 整合使用,版本問題異常
問題 artifact ons com pri connect def 中心 div jedis,spring-redis-data 整合使用,版本不匹配的時候經常會報一些異常,例如1: java.lang.NoClassDefFoundError: org/springf
Redis整合spring總結
sca eric str 綁定 apach 編寫 登錄 drive his 1 一:Redis簡介: 2 Redis是一個開源(BSD許可)的內存數據結構存儲,用作數據庫,緩存和消息代理。 3 簡單來說,它是一個以(key,value)
Redis整合Spring實現分布式鎖
gte 展示 是否 alt cep 狀態 wait 封裝 RR spring把專門的數據操作獨立封裝在spring-data系列中,spring-data-redis是對Redis的封裝 <dependencies> <!-- 添加spri
Spring Boot整合JPA、Redis和Swagger2
enc code extends art redis學習 and 小結 JD pip 好久沒有總結了,最近也一直在學習。今天就把spring boot與其它技術的整合做個小總結,主要是jpa、redis和swagger2。公司裏有用到這些,整合起來也很簡單。 首先,新建一個
Spring Boot-整合redis(六)
lec access IV 使用 tty factor cat 訪問 spa redis安裝 參考:https://www.cnblogs.com/LQBlog/p/9214517.html 單機版 1.添加pom依賴 <!-- Spring Boot R
Spring AOP整合redis 實現緩存統一管理
integer eva spring eas chm 形參 結束 system 常量 項目使用redis作為緩存數據,但面臨著問題,比如,項目A,項目B都用到redis,而且用的redis都是一套集群,這樣會帶來一些問題。問題:比如項目A的開發人員,要緩存一些熱門數據,想到
spring boot 整合redis 以一個熱門房產為例子
1.新增redis依賴 就是jedis redis.clients jedis 2.9.0 2.每次點選房屋詳情熱度加一 呼叫此方法 recommandService.increase(id);//每次點選房屋熱度加1 3.recommandService如何寫主要
redis整合spring(redisTemplate工具類) redis整合spring(redisTemplate工具類)
redis整合spring(redisTemplate工具類) 原文地址:http://blog.csdn.net/qq_34021712/article/details/75949706 ©王賽超 前言 關於哨兵模式的配置,我是參考網上
Spring Boot整合Redis實戰操作
最近在使用Spring Boot,發現其功能真是強大,可以快速的整合很多的元件功能,非常方便: 今天就來介紹下,如何整合Redis。 定義 Redis 是一個高效能的key-value資料庫。它支援儲存的value型別很多,包括string(字串)、list(連結串列)、set(集合)、zset
Spring Boot(十一)Redis整合從Docker安裝到分散式Session共享
一、簡介 Redis是一個開源的使用ANSI C語言編寫、支援網路、可基於記憶體亦可持久化的日誌型、Key-Value資料庫,並提供多種語言的API,Redis也是技術領域使用最為廣泛的儲存中介軟體,它是「Remote Dictionary Service」首字母縮寫,也就是「遠端字典服務」。 Red
Spring boot整合Redis(2)—RedisTemplate的使用來儲存Map集合
前言:上一篇文章我們用的是StringRedisTemplate,但是它存在一點問題,也迫使我重新寫了程式碼,問題是:在我們往快取中存入數字形式的String型別時,我們在利用Spring could將獲取到的資料傳送到另一服務時,我們發現數據已經被強轉為Integer型別了,因為我們可能傳輸的資料龐大,型別
Spring Boot整合Redis及RedisTemplate常用操作
Spring Boot整合Redis maven依賴 <!-- redis 依賴 --> <dependency> <groupId>org.springframework.boot</groupId> <
spring boot整合redis實戰
1.spring boot整合redis,此次專案有進行maven的相關配置工作,整個程式碼結構目錄如下: 其中pom檔案繫結相關的redis的引數步驟如下: 其中<dependency>依賴當中進新配置了相關的redis依賴,也就是spring-boot-start