征服 Redis + Jedis + Spring (一)—— 配置&常規操做(GET SET DE

我想大部分人對spring-data-hadoopspring-data-mongodbspring-data-redis以及spring-data-jpa表示關注。web

1、簡述

spring把專門的數據操做獨立封裝在spring-data系列中,spring-data-redis天然是針對Redis的獨立封裝了。redis

當前版本1.0.1,主要是將jedisjredisrjc以及srpRedis Client進行了封裝,同時支持事務。已經讓我垂涎欲滴了。固然,當前版本不支持Sharding。例如,前文曾經經過Jedis經過Client配置,實現一致性哈希,達到Sharding的目的。再一點,若是你早在spring1.x寫過SpringJdbc的話,如今會以爲似曾相識。spring

 

在通過一番思想鬥爭後,我最終放棄了Jedis原生實現,擁抱spring-data-redis了。爲何?由於,我須要一個有事務機制的框架,一個不須要顯式調用對象池操做的框架。這些spring-data-redis都解決了。至於Sharding,當前數據量要求還不大,期待Redis 3.0吧。mongodb

 

2、配置

對象池配置:app

 

Xml代碼  框架


  1. <bean  dom

  2.         id="jedisPoolConfig"  ide

  3.         class="redis.clients.jedis.JedisPoolConfig"  oop

  4.     >  ui

  5.         <property  

  6.             name="maxActive"  

  7.             value="${redis.pool.maxActive}" />  

  8.         <property  

  9.             name="maxIdle"  

  10.             value="${redis.pool.maxIdle}" />  

  11.         <property  

  12.             name="maxWait"  

  13.             value="${redis.pool.maxWait}" />  

  14.         <property  

  15.             name="testOnBorrow"  

  16.             value="${redis.pool.testOnBorrow}" />  

  17.     </bean>  

 

 

工廠實現:

 

Xml代碼  


  1. <bean  

  2.     id="jedisConnectionFactory"  

  3.     class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"  

  4. >  

  5.     <property  

  6.         name="hostName"  

  7.         value="${redis.ip}" />  

  8.     <property  

  9.         name="port"  

  10.         value="${redis.port}" />  

  11.     <property  

  12.         name="poolConfig"  

  13.         ref="jedisPoolConfig" />  

  14. </bean>  

 

 

模板類:

 

Xml代碼  


  1. <bean  

  2.         class="org.springframework.data.redis.core.RedisTemplate"  

  3.         p:connection-factory-ref="jedisConnectionFactory" />  

 

 

是否是很像配置一個JdbcTemplate?其實就這麼簡單。

redis.properties配置以下:

 

Properties代碼  


  1. #最大分配的對象數  

  2. redis.pool.maxActive=1024  

  3. #最大可以保持idel狀態的對象數  

  4. redis.pool.maxIdle=200  

  5. #當池內沒有返回對象時,最大等待時間  

  6. redis.pool.maxWait=1000  

  7. #當調用borrow Object方法時,是否進行有效性檢查  

  8. redis.pool.testOnBorrow=true  

  9.   

  10. #IP  

  11. redis.ip=10.11.20.140  

  12. #Port  

  13. redis.port=6379  

 

 

當前只能用一個節點,期待Redis 3.0,Sharding吧!

 

3、GET、SET、DEL操做

Redis初來乍練,目前也就是用Memcached多些,只會這些基本的操做,在這裏獻醜了!

 

假定作一個UserDao:

 

Java代碼  


  1. public interface UserDao {  

  2.     /** 

  3.      * @param uid 

  4.      * @param address 

  5.      */  

  6.     void save(User user);  

  7.   

  8.     /** 

  9.      * @param uid 

  10.      * @return  

  11.      */  

  12.     User read(String uid);  

  13.   

  14.     /** 

  15.      * @param uid 

  16.      */  

  17.     void delete(String uid);  

  18. }  

 

 

User對象就這麼兩個屬性:

 

Java代碼  


  1. public class User implements Serializable {  

  2.   

  3.     private static final long serialVersionUID = -1267719235225203410L;  

  4.   

  5.     private String uid;  

  6.   

  7.     private String address;  

  8. }  

 

 

實現這三個方法須要獲得RedisTemplate的支持:

 

Java代碼  


  1. @Autowired  

  2. private RedisTemplate<Serializable, Serializable> redisTemplate;  

 爲何用序列化泛型?我存的數據都是可序列化的內容。還有更多爲何?其實我也解答不了不少,邊練邊學,我弄通了必定告訴你!

 

 

1.保存-SET

 

作一個保存造做,使用RedisSET命令:

 

Java代碼  


  1. @Override  

  2. public void save(final User user) {  

  3.     redisTemplate.execute(new RedisCallback<Object>() {  

  4.         @Override  

  5.         public Object doInRedis(RedisConnection connection)  

  6.                 throws DataAccessException {  

  7.             connection.set(  

  8.                     redisTemplate.getStringSerializer().serialize(  

  9.                             "user.uid." + user.getUid()),  

  10.                     redisTemplate.getStringSerializer().serialize(  

  11.                             user.getAddress()));  

  12.             return null;  

  13.         }  

  14.     });  

  15. }  

 這裏是經過模板類,實現方法回調。在spring框架下,能夠方便的控制事務,若是你研究過spring的dao源代碼,對此必定熟悉。

 

 

  1. 傳入參數,須要final標識,禁止方法內修改。

  2. 調用RedisConnectionset方法實現RedisSET命令。

  3. 無論是Key,仍是Value都須要進行Serialize

  4. 序列化操做,最好使用RedisTemplate提供的Serializer來完成。

 

這跟當年的SpringJdbcTemplate有那麼一拼!

 

2.獲取-GET

想要將對象從Redis中取出來,就麻煩一些,須要序列化key,最好判斷下這個key是否存在,避免無用功。若是鍵值存在,須要對數據反序列化。

 

Java代碼  


  1. @Override  

  2. public User read(final String uid) {  

  3.     return redisTemplate.execute(new RedisCallback<User>() {  

  4.         @Override  

  5.         public User doInRedis(RedisConnection connection)  

  6.                 throws DataAccessException {  

  7.             byte[] key = redisTemplate.getStringSerializer().serialize(  

  8.                     "user.uid." + uid);  

  9.             if (connection.exists(key)) {  

  10.                 byte[] value = connection.get(key);  

  11.                 String address = redisTemplate.getStringSerializer()  

  12.                         .deserialize(value);  

  13.                 User user = new User();  

  14.                 user.setAddress(address);  

  15.                 user.setUid(uid);  

  16.                 return user;  

  17.             }  

  18.             return null;  

  19.         }  

  20.     });  

  21. }  

 當年寫SpringJdbc的時候,就是這樣一個字段一個字段拼裝的,甭提多累人。好吧,用Spring-Data-Redis,又讓我回歸了!

 

 

  1. 記得使用泛型,如RedisCallback<User>()

  2. 使用同一的序列化/反序列化Serializer

  3. 建議使用connection.exists(key)判別鍵值是否存在,避免無用功

 

3.刪除-DEL

刪除,就簡單點,不過也須要這樣折騰一會:

 

Java代碼  


  1. @Override  

  2. public void delete(final String uid) {  

  3.     redisTemplate.execute(new RedisCallback<Object>() {  

  4.         public Object doInRedis(RedisConnection connection) {  

  5.             connection.del(redisTemplate.getStringSerializer().serialize(  

  6.                     "user.uid." + uid));  

  7.             return null;  

  8.         }  

  9.     });  

  10. }  

 

作個TestCase,暫時夠我用了!

 

4. TestCase

 

 

Java代碼  


  1. import static org.junit.Assert.*;  

  2. import org.junit.Before;  

  3. import org.junit.Test;  

  4. import org.springframework.context.ApplicationContext;  

  5. import org.springframework.context.support.ClassPathXmlApplicationContext;  

  6. import org.zlex.redis.dao.UserDao;  

  7. import org.zlex.redis.domain.User;  

  8.   

  9. public class UserDaoTest {  

  10.     private ApplicationContext app;  

  11.     private UserDao userDao;  

  12.   

  13.     @Before  

  14.     public void before() throws Exception {  

  15.         app = new ClassPathXmlApplicationContext("applicationContext.xml");  

  16.         userDao = (UserDao) app.getBean("userDao");  

  17.     }  

  18.   

  19.     @Test  

  20.     public void crud() {  

  21.         // -------------- Create ---------------  

  22.         String uid = "u123456";  

  23.         String address1 = "上海";  

  24.         User user = new User();  

  25.         user.setAddress(address1);  

  26.         user.setUid(uid);  

  27.         userDao.save(user);  

  28.   

  29.         // ---------------Read ---------------  

  30.         user = userDao.read(uid);  

  31.   

  32.         assertEquals(address1, user.getAddress());  

  33.   

  34.         // --------------Update ------------  

  35.         String address2 = "北京";  

  36.         user.setAddress(address2);  

  37.         userDao.save(user);  

  38.   

  39.         user = userDao.read(uid);  

  40.   

  41.         assertEquals(address2, user.getAddress());  

  42.   

  43.         // --------------Delete ------------  

  44.         userDao.delete(uid);  

  45.         user = userDao.read(uid);  

  46.         assertNull(user);  

  47.     }  

  48. }  

 貌似少了update,也許之後操做Hash時,會用上。

 

看看控制檯得到了什麼: 

 

redis 127.0.0.1:6379> get user.uid.u123456
(nil)
redis 127.0.0.1:6379> get user.uid.u123456
"\xe5\x8c\x97\xe4\xba\xac"
redis 127.0.0.1:6379> get user.uid.u123456
"\xe4\xb8\x8a\xe6\xb5\xb7"
redis 127.0.0.1:6379> del user.uid.u123456
(integer) 1
redis 127.0.0.1:6379> get user.uid.u123456
(nil)
redis 127.0.0.1:6379> get user.uid.u123456
"\xe4\xb8\x8a\xe6\xb5\xb7"

若是想深刻體驗LINUX系統的新手,也能夠先下載一個方德Linux軟件中心試用一下。
免費下載地址:http://www.nfs-cloud.cn:81/appCenter/open/softcente

相關文章
相關標籤/搜索