redis 做缓存的实例

redis 做缓存的实例

由于之前对redis有了一个系统的研究,在公司的多个项目中使用redis当做数据缓存;所以趁着这些天晚上的时间,自己写了一个demo;这里仅供自己后期学习笔记参考,若有不对的地方,请轻拍砖!

redis 官网推荐给java 使用的客户端很多:Jedis、Redisson、JRedis、JDBC-Redis 等,当然首推是jedis;可以参考redis客户端官网查看。

接下来来讲下我的这个demo,我这个案例不是通过spring进行整合的redis,这个将会在之后的demo中讲到的。

(1).创建一个maven 功臣,在工程的pom 中引入jedis客户端;还有要依赖spring管理,所以也要引入spring相关jar包。

[html]  view plain  copy
  1. <span style="white-space:pre">        </span><dependency>  
  2.                 <groupId>redis.clients</groupId>  
  3.                 <artifactId>jedis</artifactId>  
  4.                 <version>${jedis-version}</version>  
  5.             </dependency>  
  6.         <dependency>  

(2).一般一个(系统)项目所用的redis服务器 多节点的集群服务器,所以会自己对(jedis)redis客户端进行封装,由于本例我自己写的是单节点,但是我还是按多节点的思路对客户端进行了封装。

redisClient类

[java]  view plain  copy
  1. /** 
  2.  * redis 客户端封装 
  3.  * @author leo 
  4.  * 
  5.  */  
  6. public class RedisClient  {  
  7.     /** 
  8.      * 日志记录 
  9.      */  
  10.     private static final Log LOG = LogFactory.getLog(RedisClient.class);  
  11.     /** 
  12.      * redis 连接池 
  13.      */  
  14.     private JedisPool pool;  
  15.       
  16.     public void setPool(JedisPool pool) {  
  17.         this.pool = pool;  
  18.     }  
  19.     /** 
  20.      * 获取jedis  
  21.      * @return 
  22.      */  
  23.     public Jedis getResource(){  
  24.         Jedis jedis =null;  
  25.         try {  
  26.             jedis =pool.getResource();  
  27.         } catch (Exception e) {  
  28.             LOG.info("can't  get  the redis resource");  
  29.         }  
  30.         return jedis;  
  31.     }  
  32.     /** 
  33.      * 关闭连接 
  34.      * @param jedis 
  35.      */  
  36.     public void disconnect(Jedis jedis){  
  37.         jedis.disconnect();  
  38.     }  
  39.     /** 
  40.      * 将jedis 返还连接池 
  41.      * @param jedis 
  42.      */  
  43.     public void returnResource(Jedis jedis){  
  44.         if(null != jedis){  
  45.             try {  
  46.                 pool.returnResource(jedis);  
  47.             } catch (Exception e) {  
  48.                 LOG.info("can't return jedis to jedisPool");  
  49.             }  
  50.         }  
  51.     }  
  52.     /** 
  53.      * 无法返还jedispool,释放jedis客户端对象, 
  54.      * @param jedis 
  55.      */  
  56.     public void brokenResource(Jedis jedis){  
  57.         if (jedis!=null) {  
  58.             try {  
  59.                 pool.returnBrokenResource(jedis);  
  60.             } catch (Exception e) {  
  61.                 LOG.info("can't release jedis Object");  
  62.             }  
  63.         }  
  64.     }  
  65. }  
然后 通过spring的bean.xml 来管理 连接池,和连接池参数配置,以及redisClient 的依赖注入。

[html]  view plain  copy
  1. <!-- jedis 连接池配置参数:  -->  
  2.         <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">  
  3.             <property name="maxActive" value="100"></property>  
  4.             <property name="maxIdle" value="25"></property>  
  5.             <property name="maxWait" value="15000"></property>  
  6.             <property name="testOnBorrow" value="false"></property>  
  7.             <property name="testOnReturn" value="false"></property>  
  8.         </bean>  
  9.         <!-- jedis 连接池  连接本地redis服务 构造器注入-->  
  10.         <bean id="pool" class="redis.clients.jedis.JedisPool">  
  11.             <constructor-arg index="0"  ref="poolConfig"/>   
  12.             <constructor-arg index="1" value="10.224.68.46"/>   
  13.             <constructor-arg index="2" value="6379"/>  
  14.             <constructor-arg index="3" value="2000"/>   
  15.         </bean>  
  16.         <!-- cleint-->  
  17.         <bean id="redisClient" class="com.deppon.cache.redis.RedisClient">  
  18.             <property name="pool" ref="pool"/>  
  19.         </bean>  
(3).创建好redisClient 之后,我要创造一个存储器,即一个对redis操作的工具容器。由于是公共容器,所以我创建接口是的容器接口就不该是封闭的,应该是开封的,保证存入数据库中对象类型的多态性。

存储器接口:

[java]  view plain  copy
  1. /** 
  2.  *  
  3.  * @author leo 
  4.  *缓存存储接口 
  5.  * @param <K> key 
  6.  * @param <V> value 
  7.  */  
  8. public interface RedisCacheStorage<K, V> {  
  9.     /** 
  10.      * 在redis数据库中插入 key  和value 
  11.      * @param key 
  12.      * @param value 
  13.      * @return 
  14.      */  
  15.     boolean set(K key,V value);  
  16.     /** 
  17.      * 在redis数据库中插入 key  和value 并且设置过期时间 
  18.      * @param key 
  19.      * @param value 
  20.      * @param exp 过期时间 s 
  21.      * @return 
  22.      */  
  23.     boolean set(K key, V value, int exp);  
  24.     /** 
  25.      * 根据key 去redis 中获取value 
  26.      * @param key 
  27.      * @return 
  28.      */  
  29.     V get(K key);  
  30.     /** 
  31.      * 删除redis库中的数据 
  32.      * @param key 
  33.      * @return 
  34.      */  
  35.     boolean remove(K key);  
  36.     /** 
  37.      * 设置哈希类型数据到redis 数据库 
  38.      * @param cacheKey 可以看做一张表 
  39.      * @param key   表字段 
  40.      * @param value   
  41.      * @return 
  42.      */  
  43.     boolean hset(String cacheKey,K key,V value);  
  44.     /** 
  45.      * 获取哈希表数据类型的值 
  46.      * @param cacheKey 
  47.      * @param key 
  48.      * @return 
  49.      */  
  50.     V hget(String cacheKey,K key);  
  51.     /** 
  52.      * 获取哈希类型的数据 
  53.      * @param cacheKey 
  54.      * @return 
  55.      */  
  56.     Map<K,V> hget(String cacheKey);  
以及存储实现类:

[java]  view plain  copy
  1. /** 
  2.  * redis 缓存存储器实现 
  3.  * @author leo 
  4.  * 
  5.  * @param <V> 
  6.  */  
  7. public class RedisCacheStorageImpl<V> implements RedisCacheStorage<String, V> {  
  8.     /** 
  9.      * 日志记录 
  10.      */  
  11.     public static final Log LOG = LogFactory.getLog(RedisCacheStorageImpl.class);  
  12.     /** 
  13.      * redis 客户端 
  14.      */  
  15.     private RedisClient redisClient;  
  16.     /** 
  17.      * 默认过时时间 
  18.      */  
  19.     private static final int EXPRIE_TIME =3600*24;   
  20.       
  21.     public void setRedisClient(RedisClient redisClient) {  
  22.         this.redisClient = redisClient;  
  23.     }  
  24.     /** 
  25.      * 在redis数据库中插入 key  和value 
  26.      * @param key 
  27.      * @param value 
  28.      * @return 
  29.      */  
  30.     @Override  
  31.     public boolean set(String key, V value) {  
  32.         //设置默认过时时间  
  33.         return set(key, value, EXPRIE_TIME);  
  34.     }  
  35.     /** 
  36.      * 在redis数据库中插入 key  和value 并且设置过期时间 
  37.      * @param key 
  38.      * @param value 
  39.      * @param exp 过期时间 s 
  40.      * @return 
  41.      */  
  42.     @SuppressWarnings("finally")  
  43.     @Override  
  44.     public boolean set(String key, V value, int exp) {  
  45.         Jedis jedis =null;  
  46.         //将key 和value  转换成 json 对象  
  47.         String jKey =CacheUtils.toJsonString(key);  
  48.         String jValue =CacheUtils.toJsonString(value);  
  49.         //操作是否成功  
  50.         boolean isSucess =true;  
  51.         if(StringUtils.isNotEmpty(jKey)){  
  52.             LOG.info("key is empty");  
  53.             return false;  
  54.         }  
  55.         try {  
  56.             //获取客户端对象  
  57.             jedis =redisClient.getResource();  
  58.             //执行插入  
  59.             jedis.setex(jKey, exp, jValue);  
  60.         } catch (JedisException e) {  
  61.             LOG.info("client can't connect server");  
  62.             isSucess =false;  
  63.             if(null !=jedis){  
  64.                 //释放jedis对象  
  65.                 redisClient.brokenResource(jedis);  
  66.             }  
  67.             return false;  
  68.         }finally{  
  69.             if(isSucess){  
  70.                 //返还连接池  
  71.                 redisClient.returnResource(jedis);  
  72.             }  
  73.             return true;  
  74.         }  
  75.     }  
  76.     /** 
  77.      * 根据key 去redis 中获取value 
  78.      * @param key 
  79.      * @return 
  80.      */  
  81.     @SuppressWarnings("unchecked")  
  82.     @Override  
  83.     public V get(String key) {  
  84.         Jedis jedis =null;  
  85.         //将key 和value  转换成 json 对象  
  86.         String jKey =CacheUtils.toJsonString(key);  
  87.         V jValue =null;  
  88.         //key 不能为空  
  89.         if(StringUtils.isEmpty(jKey)){  
  90.             LOG.info("key is empty");  
  91.             return null;  
  92.         }  
  93.         try {  
  94.             //获取客户端对象  
  95.             jedis =redisClient.getResource();  
  96.             //执行查询  
  97.             String value =  jedis.get(jKey);  
  98.             //判断值是否非空  
  99.             if(StringUtils.isEmpty(value)){  
  100.                 return null;  
  101.             }else{  
  102.                 jValue= (V) CacheUtils.jsonParseObject(value);  
  103.             }  
  104.             //返还连接池  
  105.             redisClient.returnResource(jedis);  
  106.         } catch (JedisException e) {  
  107.             LOG.info("client can't connect server");  
  108.             if(null !=jedis){  
  109.                 //释放jedis 对象  
  110.                 redisClient.brokenResource(jedis);  
  111.             }  
  112.         }  
  113.         return jValue;  
  114.     }  
  115.     /** 
  116.      * 删除redis库中的数据 
  117.      * @param key 
  118.      * @return 
  119.      */  
  120.     @SuppressWarnings("finally")  
  121.     @Override  
  122.     public boolean remove(String key) {  
  123.         Jedis jedis =null;  
  124.         //将key 和value  转换成 json 对象  
  125.         String jKey =CacheUtils.toJsonString(key);  
  126.         //操作是否成功  
  127.         boolean isSucess =true;  
  128.         if(StringUtils.isEmpty(jKey)){  
  129.             LOG.info("key is empty");  
  130.             return false;  
  131.         }  
  132.         try {  
  133.             jedis =redisClient.getResource();  
  134.             //执行删除  
  135.             jedis.del(jKey);  
  136.         } catch (JedisException e) {  
  137.             LOG.info("client can't connect server");  
  138.             isSucess =false;  
  139.             if(null !=jedis){  
  140.                 //释放jedis 对象  
  141.                 redisClient.brokenResource(jedis);  
  142.             }  
  143.             return false;  
  144.         }finally{  
  145.             if (isSucess) {  
  146.                 //返还连接池  
  147.                 redisClient.returnResource(jedis);  
  148.             }  
  149.             return true;  
  150.         }  
  151.     }  
  152.     /** 
  153.      * 设置哈希类型数据到redis 数据库 
  154.      * @param cacheKey 可以看做一张表 
  155.      * @param key   表字段 
  156.      * @param value   
  157.      * @return 
  158.      */  
  159.     @SuppressWarnings("finally")  
  160.     @Override  
  161.     public boolean hset(String cacheKey, String key, V value) {  
  162.         Jedis jedis =null;  
  163.         //将key 和value  转换成 json 对象  
  164.         String jKey =CacheUtils.toJsonString(key);  
  165.         String jCacheKey =CacheUtils.toJsonString(cacheKey);  
  166.         String jValue =CacheUtils.toJsonString(value);  
  167.         //操作是否成功  
  168.         boolean isSucess =true;  
  169.         if(StringUtils.isEmpty(jCacheKey)){  
  170.             LOG.info("cacheKey is empty");  
  171.             return false;  
  172.         }  
  173.         try {  
  174.             jedis =redisClient.getResource();  
  175.             //执行插入哈希  
  176.             jedis.hset(jCacheKey, jKey, jValue);  
  177.         } catch (JedisException e) {  
  178.             LOG.info("client can't connect server");  
  179.             isSucess =false;  
  180.             if(null !=jedis){  
  181.                 //释放jedis 对象  
  182.                 redisClient.brokenResource(jedis);  
  183.             }  
  184.             return false;  
  185.         }finally{  
  186.             if (isSucess) {  
  187.                 //返还连接池  
  188.                 redisClient.returnResource(jedis);  
  189.             }  
  190.             return true;  
  191.         }  
  192.     }  
  193.     /** 
  194.      * 获取哈希表数据类型的值 
  195.      * @param cacheKey 
  196.      * @param key 
  197.      * @return 
  198.      */  
  199.     @SuppressWarnings("unchecked")  
  200.     @Override  
  201.     public V hget(String cacheKey, String key) {  
  202.         Jedis jedis =null;  
  203.         //将key 和value  转换成 json 对象  
  204.         String jKey =CacheUtils.toJsonString(key);  
  205.         String jCacheKey =CacheUtils.toJsonString(cacheKey);  
  206.         V jValue =null;  
  207.         if(StringUtils.isEmpty(jCacheKey)){  
  208.             LOG.info("cacheKey is empty");  
  209.             return null;  
  210.         }  
  211.         try {  
  212.             //获取客户端对象  
  213.             jedis =redisClient.getResource();  
  214.             //执行查询  
  215.             String value =  jedis.hget(jCacheKey, jKey);  
  216.             //判断值是否非空  
  217.             if(StringUtils.isEmpty(value)){  
  218.                 return null;  
  219.             }else{  
  220.                 jValue= (V) CacheUtils.jsonParseObject(value);  
  221.             }  
  222.             //返还连接池  
  223.             redisClient.returnResource(jedis);  
  224.         } catch (JedisException e) {  
  225.             LOG.info("client can't connect server");  
  226.             if(null !=jedis){  
  227.                 //释放jedis 对象  
  228.                 redisClient.brokenResource(jedis);  
  229.             }  
  230.         }  
  231.         return jValue;  
  232.     }  
  233.     /** 
  234.      * 获取哈希类型的数据 
  235.      * @param cacheKey 
  236.      * @return 
  237.      */  
  238.     @Override  
  239.     public Map<String, V> hget(String cacheKey) {  
  240.         String jCacheKey =CacheUtils.toJsonString(cacheKey);  
  241.         //非空校验  
  242.         if(StringUtils.isEmpty(jCacheKey)){  
  243.             LOG.info("cacheKey is empty!");  
  244.             return null;  
  245.         }  
  246.         Jedis jedis =null;  
  247.         Map<String,V> result =null;  
  248.         try {  
  249.             jedis =redisClient.getResource();  
  250.             //获取列表集合  
  251.             Map<String,String> map = jedis.hgetAll(jCacheKey);   
  252.               
  253.             if(null !=map){  
  254.                 for(Map.Entry<String, String> entry : map.entrySet()){  
  255.                     if(result ==null){  
  256.                         result =new HashMap<String,V>();  
  257.                     }  
  258.                     result.put((String) CacheUtils.jsonParseObject(entry.getKey()), (V)CacheUtils.jsonParseObject(entry.getValue()));  
  259.                 }  
  260.             }  
  261.         } catch (JedisException e) {  
  262.             LOG.info("client can't connect server");  
  263.             if(null !=jedis){  
  264.                 //释放jedis 对象  
  265.                 redisClient.brokenResource(jedis);  
  266.             }  
  267.         }  
  268.         return result;  
  269.     }  
  270.   
  271. }  
(4),接下来要把写个具体的业务UserService,来测试redis的存储器在具体业务中的使用,即实现(非关系型数据库的持久化操作)。本例中的例子是经常项目中对user的操作

创建UserEntity实体类:

[java]  view plain  copy
  1. /** 
  2.  * 用户实体类 
  3.  * @author leo 
  4.  * 
  5.  */  
  6. public class UserEntity {  
  7.     //用户id  
  8.     private String userId;  
  9.     //用户账号  
  10.     private String EmpCode;  
  11.     //用户名称  
  12.     private String EmpName;  
  13.     //用户角色  
  14.     private String role;  
  15.     //职位  
  16.     private String title;  
  17.     public String getUserId() {  
  18.         return userId;  
  19.     }  
  20.     public void setUserId(String userId) {  
  21.         this.userId = userId;  
  22.     }  
  23.     public String getEmpCode() {  
  24.         return EmpCode;  
  25.     }  
  26.     public void setEmpCode(String empCode) {  
  27.         EmpCode = empCode;  
  28.     }  
  29.     public String getEmpName() {  
  30.         return EmpName;  
  31.     }  
  32.     public void setEmpName(String empName) {  
  33.         EmpName = empName;  
  34.     }  
  35.     public String getRole() {  
  36.         return role;  
  37.     }  
  38.     public void setRole(String role) {  
  39.         this.role = role;  
  40.     }  
  41.     public String getTitle() {  
  42.         return title;  
  43.     }  
  44.     public void setTitle(String title) {  
  45.         this.title = title;  
  46.     }  
然后创建用户操作的业务层Service;由于这里主要是测试NOSQL的数据持久化,所以就忽略了对数据库持久化层(DAO)的操作。

userServiceImpl类:

[java]  view plain  copy
  1. /** 
  2.  * 业务层接口实现 
  3.  * @author leo 
  4.  * 
  5.  */  
  6. public class UserServiceImpl implements IUserService {  
  7.     private static final String  cacheKey  ="userEntity";  
  8.     /** 
  9.      * 缓存存储 
  10.      */  
  11.     private RedisCacheStorageImpl<UserEntity> storageCache;  
  12.       
  13.     public void setStorageCache(RedisCacheStorageImpl<UserEntity> storageCache) {  
  14.         this.storageCache = storageCache;  
  15.     }  
  16.     /** 
  17.      * 新增 
  18.      * @param entity 
  19.      * @return 
  20.      */  
  21.     @Override  
  22.     public boolean addUserEntity(UserEntity entity) {  
  23.         //非空  
  24.         if(entity ==null || StringUtils.isEmpty(entity.getUserId())){  
  25.             return false;  
  26.         }  
  27.         /** 
  28.          * 做数据库持久化,这里就无需再申明了 
  29.          */  
  30.         System.out.println("先插入数据库中,.........");  
  31.         //然后接下来做非关系型数据库持久化  
  32.         return storageCache.hset(cacheKey, entity.getUserId(), entity);  
  33.     }  
  34.   
  35.     @Override  
  36.     public boolean deleteUserEntity(UserEntity entity) {  
  37.           
  38.         return false;  
  39.     }  
  40.     /** 
  41.      * 根据id 查询 
  42.      * @return 
  43.      */  
  44.     @Override  
  45.     public UserEntity queryUserEntityByUserId(UserEntity userEntity) {  
  46.         //非空  
  47.         if(userEntity ==null || StringUtils.isEmpty(userEntity.getUserId())){  
  48.             return null;  
  49.         }  
  50.         //先去缓存中查询 是否存在,不存在在查询  
  51.          UserEntity reslut = storageCache.hget(cacheKey, userEntity.getUserId());  
  52.         if(reslut!=null){  
  53.             return reslut;  
  54.         }else{  
  55.             //查询数据库  
  56.             System.out.println("查询数据库");  
  57.         }  
  58.         return null;  
  59.     }  
  60.   
  61. }  
以及spring-bean.xml的配置对业务层的管理:

[html]  view plain  copy
  1. <!-- storge Cache 存储器-->  
  2.         <bean id="storageCache" class="com.deppon.cache.storage.impl.RedisCacheStorageImpl">  
  3.             <property name="redisClient" ref="redisClient" />  
  4.         </bean>  
  5.         <bean id="userServiceImpl" class="com.deppon.cache.service.impl.UserServiceImpl">  
  6.             <property name="storageCache" ref="storageCache"/>  
  7.         </bean>  
(6).最后写个junit 测下,查看是否有没有插入到redis库中

[html]  view plain  copy
  1. public class TestUserServiceImpl {  
  2.     /**  
  3.      * 用户接口  
  4.      */  
  5.     private IUserService userServiceImpl;  
  6.       
  7.     public void setUserServiceImpl(IUserService userServiceImpl) {  
  8.         this.userServiceImpl = userServiceImpl;  
  9.     }  
  10.     @Before  
  11.     public void setUp() throws Exception {  
  12.         userServiceImpl = (IUserService) SpringTestHelper.get().getBeanByClass(UserServiceImpl.class);  
  13.     }  
  14.   
  15.     @After  
  16.     public void tearDown() throws Exception {  
  17.     }  
  18.     @Test  
  19.     public void testAdd(){  
  20.         UserEntity entity = new UserEntity();  
  21.         entity.setUserId("000001");  
  22.         entity.setEmpCode("130566");  
  23.         entity.setEmpName("leonardo-zeng");  
  24.         entity.setRole("Java Development Engineer");  
  25.         entity.setTitle("PM");  
  26.         boolean isTrue =userServiceImpl.addUserEntity(entity);  
  27.         Assert.assertTrue(isTrue);  
  28.     }  
  29.       
  30.     @Test  
  31.     public void testQueryById(){  
  32.         UserEntity entity = new UserEntity();  
  33.         entity.setUserId("000001");  
  34.         UserEntity userEntity =userServiceImpl.queryUserEntityByUserId(entity);  
  35.         System.out.println(userEntity);  
  36.     }  
  37. }  
连接redis库,查询出来的确值在库中存在

redis 127.0.0.1:6379> hkeys "\"userEntity\""
1) "\"000001\""
redis 127.0.0.1:6379> hget "\"userEntity\"" "\"000001\""
"{\"@type\":\"com.deppon.cache.entity.UserEntity\",\"empCode\":\"130566\",\"empN
ame\":\"leonardo-zeng\",\"role\":\"Java Development Engineer\",\"title\":\"PM\",
\"userId\":\"000001\"}"
redis 127.0.0.1:6379>
整个demo就这样了

猜你喜欢

转载自blog.csdn.net/u010681191/article/details/79748253