SpringDataRedis:第一章:簡介
SpringDataRedis簡介
項(xiàng)目常見問題思考
我們目前的系統(tǒng)已經(jīng)實(shí)現(xiàn)了廣告后臺管理和廣告前臺展示,但是對于首頁每天有大量的人訪問,對數(shù)據(jù)庫造成很大的訪問壓力,甚至是癱瘓。那如何解決呢?我們通常的做法有兩種:一種是數(shù)據(jù)緩存、一種是網(wǎng)頁靜態(tài)化。我們今天討論第一種解決方案。
Redis
redis是一款開源的Key-Value數(shù)據(jù)庫,運(yùn)行在內(nèi)存中,由ANSI C編寫。企業(yè)開發(fā)通常采用Redis來實(shí)現(xiàn)緩存。同類的產(chǎn)品還有memcache 、memcached 、MongoDB等。
Jedis
Jedis是Redis官方推出的一款面向Java的客戶端,提供了很多接口供Java語言調(diào)用??梢栽赗edis官網(wǎng)下載,當(dāng)然還有一些開源愛好者提供的客戶端,如Jredis、SRP等等,推薦使用Jedis。
Spring Data Redis
Spring-data-redis是spring大家族的一部分,提供了在srping應(yīng)用中通過簡單的配置訪問redis服務(wù),對reids底層開發(fā)包(Jedis, JRedis, and RJC)進(jìn)行了高度封裝,RedisTemplate提供了redis各種操作、異常處理及序列化,支持發(fā)布訂閱,并對spring 3.1 cache進(jìn)行了實(shí)現(xiàn)。
spring-data-redis針對jedis提供了如下功能:
1.連接池自動(dòng)管理,提供了一個(gè)高度封裝的“RedisTemplate”類
2.針對jedis客戶端中大量api進(jìn)行了歸類封裝,將同一類型操作封裝為operation接口
ValueOperations:簡單K-V操作
SetOperations:set類型數(shù)據(jù)操作
ZSetOperations:zset類型數(shù)據(jù)操作
HashOperations:針對map類型的數(shù)據(jù)操作
ListOperations:針對list類型的數(shù)據(jù)操作
Spring Data Redis入門小Demo
準(zhǔn)備工作
(1)構(gòu)建Maven工程 SpringDataRedisDemo
(2)引入Spring相關(guān)依賴、引入JUnit依賴 (內(nèi)容參加其它工程)
(3)引入Jedis和SpringDataRedis依賴
<!-- 緩存 -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.8.1</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.7.2.RELEASE</version>
</dependency>
在src/main/resources下創(chuàng)建properties文件夾,建立redis-config.properties
redis.host=127.0.0.1
redis.port=6379
redis.pass=
redis.database=0
redis.maxIdle=300
redis.maxWait=3000
redis.testOnBorrow=true
(5)在src/main/resources下創(chuàng)建spring文件夾 ,創(chuàng)建applicationContext-redis.xml
<context:property-placeholder location="classpath*:properties/*.properties" />
<!-- redis 相關(guān)配置 -->
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxIdle" value="${redis.maxIdle}" />
<property name="maxWaitMillis" value="${redis.maxWait}" />
<property name="testOnBorrow" value="${redis.testOnBorrow}" />
</bean>
<bean id="JedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
p:host-name="${redis.host}" p:port="${redis.port}" p:password="${redis.pass}" p:pool-config-ref="poolConfig"/>
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="JedisConnectionFactory" />
</bean>
maxIdle :最大空閑數(shù)
maxWaitMillis:連接時(shí)的最大等待毫秒數(shù)
testOnBorrow:在提取一個(gè)jedis實(shí)例時(shí),是否提前進(jìn)行驗(yàn)證操作;如果為true,則得到的jedis實(shí)例均是可用的;
值類型操作
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:spring/applicationContext-redis.xml")
public class TestValue {
@Autowired
private RedisTemplate redisTemplate;
@Test
public void setValue(){
redisTemplate.boundValueOps("name").set("itcast");
}
@Test
public void getValue(){
String str = (String) redisTemplate.boundValueOps("name").get();
System.out.println(str);
}
@Test
public void deleteValue(){
redisTemplate.delete("name");;
}
}
Set類型操作
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:spring/applicationContext-redis.xml")
public class TestSet {
@Autowired
private RedisTemplate redisTemplate;
/**
* 存入值
*/
@Test
public void setValue(){
redisTemplate.boundSetOps("nameset").add("曹操");
redisTemplate.boundSetOps("nameset").add("劉備");
redisTemplate.boundSetOps("nameset").add("孫權(quán)");
}
/**
* 提取值
*/
@Test
public void getValue(){
Set members = redisTemplate.boundSetOps("nameset").members();
System.out.println(members);
}
/**
* 刪除集合中的某一個(gè)值
*/
@Test
public void deleteValue(){
redisTemplate.boundSetOps("nameset").remove("孫權(quán)");
}
/**
* 刪除整個(gè)集合
*/
@Test
public void deleteAllValue(){
redisTemplate.delete("nameset");
}
}
List類型操作
創(chuàng)建測試類TestList
(1)右壓棧
/**
* 右壓棧:后添加的對象排在后邊
*/
@Test
public void testSetValue1(){
redisTemplate.boundListOps("namelist1").rightPush("劉備");
redisTemplate.boundListOps("namelist1").rightPush("關(guān)羽");
redisTemplate.boundListOps("namelist1").rightPush("張飛");
}
/**
* 顯示右壓棧集合
*/
@Test
public void testGetValue1(){
List list = redisTemplate.boundListOps("namelist1").range(0, 10);
System.out.println(list);
}
運(yùn)行結(jié)果:
[劉備, 關(guān)羽, 張飛]
(2)左壓棧
/**
* 左壓棧:后添加的對象排在前邊
*/
@Test
public void testSetValue2(){
redisTemplate.boundListOps("namelist2").leftPush("劉備");
redisTemplate.boundListOps("namelist2").leftPush("關(guān)羽");
redisTemplate.boundListOps("namelist2").leftPush("張飛");
}
/**
* 顯示左壓棧集合
*/
@Test
public void testGetValue2(){
List list = redisTemplate.boundListOps("namelist2").range(0, 10);
System.out.println(list);
}
運(yùn)行結(jié)果:
[張飛, 關(guān)羽, 劉備]
根據(jù)索引查詢元素
/**
* 查詢集合某個(gè)元素
*/
@Test
public void testSearchByIndex(){
String s = (String) redisTemplate.boundListOps("namelist1").index(1);
System.out.println(s);
}
移除某個(gè)元素的值
/**
* 移除集合某個(gè)元素
*/
@Test
public void testRemoveByIndex(){
redisTemplate.boundListOps("namelist1").remove(1, "關(guān)羽");
}
Hash類型操作
創(chuàng)建測試類TestHash
(1)存入值
@Test
public void testSetValue(){
redisTemplate.boundHashOps("namehash").put("a", "唐僧");
redisTemplate.boundHashOps("namehash").put("b", "悟空");
redisTemplate.boundHashOps("namehash").put("c", "八戒");
redisTemplate.boundHashOps("namehash").put("d", "沙僧");
}
(2)提取所有的KEY
@Test
public void testGetKeys(){
Set s = redisTemplate.boundHashOps("namehash").keys();
System.out.println(s);
}
運(yùn)行結(jié)果:
[a, b, c, d]
(3)提取所有的值
@Test
public void testGetValues(){
List values = redisTemplate.boundHashOps("namehash").values();
System.out.println(values);
}
運(yùn)行結(jié)果:
[唐僧, 悟空, 八戒, 沙僧]
(4)根據(jù)KEY提取值
@Test
public void testGetValueByKey(){
Object object = redisTemplate.boundHashOps("namehash").get("b");
System.out.println(object);
}
運(yùn)行結(jié)果:
悟空
(5)根據(jù)KEY移除值
@Test
public void testRemoveValueByKey(){
redisTemplate.boundHashOps("namehash").delete("c");
}
運(yùn)行后再次查看集合內(nèi)容:
[唐僧, 悟空, 沙僧]