redis做缓存的简单实例

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

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

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

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

<span style="white-space:pre">        </span><dependency>  
                <groupId>redis.clients</groupId>  
                <artifactId>jedis</artifactId>  
                <version>${jedis-version}</version>  
            </dependency>  
        <dependency>  

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

redisClient类

/** 
 * redis 客户端封装 
 * @author leo 
 * 
 */  
public class RedisClient  {  
    /** 
     * 日志记录 
     */  
    private static final Log LOG = LogFactory.getLog(RedisClient.class);  
    /** 
     * redis 连接池 
     */  
    private JedisPool pool;  
      
    public void setPool(JedisPool pool) {  
        this.pool = pool;  
    }  
    /** 
     * 获取jedis  
     * @return 
     */  
    public Jedis getResource(){  
        Jedis jedis =null;  
        try {  
            jedis =pool.getResource();  
        } catch (Exception e) {  
            LOG.info("can't  get  the redis resource");  
        }  
        return jedis;  
    }  
    /** 
     * 关闭连接 
     * @param jedis 
     */  
    public void disconnect(Jedis jedis){  
        jedis.disconnect();  
    }  
    /** 
     * 将jedis 返还连接池 
     * @param jedis 
     */  
    public void returnResource(Jedis jedis){  
        if(null != jedis){  
            try {  
                pool.returnResource(jedis);  
            } catch (Exception e) {  
                LOG.info("can't return jedis to jedisPool");  
            }  
        }  
    }  
    /** 
     * 无法返还jedispool,释放jedis客户端对象, 
     * @param jedis 
     */  
    public void brokenResource(Jedis jedis){  
        if (jedis!=null) {  
            try {  
                pool.returnBrokenResource(jedis);  
            } catch (Exception e) {  
                LOG.info("can't release jedis Object");  
            }  
        }  
    }  
}  

然后 通过spring的bean.xml 来管理 连接池,和连接池参数配置,以及redisClient 的依赖注入。

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

存储器接口:

/** 
 *  
 * @author leo 
 *缓存存储接口 
 * @param <K> key 
 * @param <V> value 
 */  
public interface RedisCacheStorage<K, V> {  
    /** 
     * 在redis数据库中插入 key  和value 
     * @param key 
     * @param value 
     * @return 
     */  
    boolean set(K key,V value);  
    /** 
     * 在redis数据库中插入 key  和value 并且设置过期时间 
     * @param key 
     * @param value 
     * @param exp 过期时间 s 
     * @return 
     */  
    boolean set(K key, V value, int exp);  
    /** 
     * 根据key 去redis 中获取value 
     * @param key 
     * @return 
     */  
    V get(K key);  
    /** 
     * 删除redis库中的数据 
     * @param key 
     * @return 
     */  
    boolean remove(K key);  
    /** 
     * 设置哈希类型数据到redis 数据库 
     * @param cacheKey 可以看做一张表 
     * @param key   表字段 
     * @param value   
     * @return 
     */  
    boolean hset(String cacheKey,K key,V value);  
    /** 
     * 获取哈希表数据类型的值 
     * @param cacheKey 
     * @param key 
     * @return 
     */  
    V hget(String cacheKey,K key);  
    /** 
     * 获取哈希类型的数据 
     * @param cacheKey 
     * @return 
     */  
    Map<K,V> hget(String cacheKey);  

以及存储实现类:

/** 
 * redis 缓存存储器实现 
 * @author leo 
 * 
 * @param <V> 
 */  
public class RedisCacheStorageImpl<V> implements RedisCacheStorage<String, V> {  
    /** 
     * 日志记录 
     */  
    public static final Log LOG = LogFactory.getLog(RedisCacheStorageImpl.class);  
    /** 
     * redis 客户端 
     */  
    private RedisClient redisClient;  
    /** 
     * 默认过时时间 
     */  
    private static final int EXPRIE_TIME =3600*24;   
      
    public void setRedisClient(RedisClient redisClient) {  
        this.redisClient = redisClient;  
    }  
    /** 
     * 在redis数据库中插入 key  和value 
     * @param key 
     * @param value 
     * @return 
     */  
    @Override  
    public boolean set(String key, V value) {  
        //设置默认过时时间  
        return set(key, value, EXPRIE_TIME);  
    }  
    /** 
     * 在redis数据库中插入 key  和value 并且设置过期时间 
     * @param key 
     * @param value 
     * @param exp 过期时间 s 
     * @return 
     */  
    @SuppressWarnings("finally")  
    @Override  
    public boolean set(String key, V value, int exp) {  
        Jedis jedis =null;  
        //将key 和value  转换成 json 对象  
        String jKey =CacheUtils.toJsonString(key);  
        String jValue =CacheUtils.toJsonString(value);  
        //操作是否成功  
        boolean isSucess =true;  
        if(StringUtils.isNotEmpty(jKey)){  
            LOG.info("key is empty");  
            return false;  
        }  
        try {  
            //获取客户端对象  
            jedis =redisClient.getResource();  
            //执行插入  
            jedis.setex(jKey, exp, jValue);  
        } catch (JedisException e) {  
            LOG.info("client can't connect server");  
            isSucess =false;  
            if(null !=jedis){  
                //释放jedis对象  
                redisClient.brokenResource(jedis);  
            }  
            return false;  
        }finally{  
            if(isSucess){  
                //返还连接池  
                redisClient.returnResource(jedis);  
            }  
            return true;  
        }  
    }  
    /** 
     * 根据key 去redis 中获取value 
     * @param key 
     * @return 
     */  
    @SuppressWarnings("unchecked")  
    @Override  
    public V get(String key) {  
        Jedis jedis =null;  
        //将key 和value  转换成 json 对象  
        String jKey =CacheUtils.toJsonString(key);  
        V jValue =null;  
        //key 不能为空  
        if(StringUtils.isEmpty(jKey)){  
            LOG.info("key is empty");  
            return null;  
        }  
        try {  
            //获取客户端对象  
            jedis =redisClient.getResource();  
            //执行查询  
            String value =  jedis.get(jKey);  
            //判断值是否非空  
            if(StringUtils.isEmpty(value)){  
                return null;  
            }else{  
                jValue= (V) CacheUtils.jsonParseObject(value);  
            }  
            //返还连接池  
            redisClient.returnResource(jedis);  
        } catch (JedisException e) {  
            LOG.info("client can't connect server");  
            if(null !=jedis){  
                //释放jedis 对象  
                redisClient.brokenResource(jedis);  
            }  
        }  
        return jValue;  
    }  
    /** 
     * 删除redis库中的数据 
     * @param key 
     * @return 
     */  
    @SuppressWarnings("finally")  
    @Override  
    public boolean remove(String key) {  
        Jedis jedis =null;  
        //将key 和value  转换成 json 对象  
        String jKey =CacheUtils.toJsonString(key);  
        //操作是否成功  
        boolean isSucess =true;  
        if(StringUtils.isEmpty(jKey)){  
            LOG.info("key is empty");  
            return false;  
        }  
        try {  
            jedis =redisClient.getResource();  
            //执行删除  
            jedis.del(jKey);  
        } catch (JedisException e) {  
            LOG.info("client can't connect server");  
            isSucess =false;  
            if(null !=jedis){  
                //释放jedis 对象  
                redisClient.brokenResource(jedis);  
            }  
            return false;  
        }finally{  
            if (isSucess) {  
                //返还连接池  
                redisClient.returnResource(jedis);  
            }  
            return true;  
        }  
    }  
    /** 
     * 设置哈希类型数据到redis 数据库 
     * @param cacheKey 可以看做一张表 
     * @param key   表字段 
     * @param value   
     * @return 
     */  
    @SuppressWarnings("finally")  
    @Override  
    public boolean hset(String cacheKey, String key, V value) {  
        Jedis jedis =null;  
        //将key 和value  转换成 json 对象  
        String jKey =CacheUtils.toJsonString(key);  
        String jCacheKey =CacheUtils.toJsonString(cacheKey);  
        String jValue =CacheUtils.toJsonString(value);  
        //操作是否成功  
        boolean isSucess =true;  
        if(StringUtils.isEmpty(jCacheKey)){  
            LOG.info("cacheKey is empty");  
            return false;  
        }  
        try {  
            jedis =redisClient.getResource();  
            //执行插入哈希  
            jedis.hset(jCacheKey, jKey, jValue);  
        } catch (JedisException e) {  
            LOG.info("client can't connect server");  
            isSucess =false;  
            if(null !=jedis){  
                //释放jedis 对象  
                redisClient.brokenResource(jedis);  
            }  
            return false;  
        }finally{  
            if (isSucess) {  
                //返还连接池  
                redisClient.returnResource(jedis);  
            }  
            return true;  
        }  
    }  
    /** 
     * 获取哈希表数据类型的值 
     * @param cacheKey 
     * @param key 
     * @return 
     */  
    @SuppressWarnings("unchecked")  
    @Override  
    public V hget(String cacheKey, String key) {  
        Jedis jedis =null;  
        //将key 和value  转换成 json 对象  
        String jKey =CacheUtils.toJsonString(key);  
        String jCacheKey =CacheUtils.toJsonString(cacheKey);  
        V jValue =null;  
        if(StringUtils.isEmpty(jCacheKey)){  
            LOG.info("cacheKey is empty");  
            return null;  
        }  
        try {  
            //获取客户端对象  
            jedis =redisClient.getResource();  
            //执行查询  
            String value =  jedis.hget(jCacheKey, jKey);  
            //判断值是否非空  
            if(StringUtils.isEmpty(value)){  
                return null;  
            }else{  
                jValue= (V) CacheUtils.jsonParseObject(value);  
            }  
            //返还连接池  
            redisClient.returnResource(jedis);  
        } catch (JedisException e) {  
            LOG.info("client can't connect server");  
            if(null !=jedis){  
                //释放jedis 对象  
                redisClient.brokenResource(jedis);  
            }  
        }  
        return jValue;  
    }  
    /** 
     * 获取哈希类型的数据 
     * @param cacheKey 
     * @return 
     */  
    @Override  
    public Map<String, V> hget(String cacheKey) {  
        String jCacheKey =CacheUtils.toJsonString(cacheKey);  
        //非空校验  
        if(StringUtils.isEmpty(jCacheKey)){  
            LOG.info("cacheKey is empty!");  
            return null;  
        }  
        Jedis jedis =null;  
        Map<String,V> result =null;  
        try {  
            jedis =redisClient.getResource();  
            //获取列表集合  
            Map<String,String> map = jedis.hgetAll(jCacheKey);   
              
            if(null !=map){  
                for(Map.Entry<String, String> entry : map.entrySet()){  
                    if(result ==null){  
                        result =new HashMap<String,V>();  
                    }  
                    result.put((String) CacheUtils.jsonParseObject(entry.getKey()), (V)CacheUtils.jsonParseObject(entry.getValue()));  
                }  
            }  
        } catch (JedisException e) {  
            LOG.info("client can't connect server");  
            if(null !=jedis){  
                //释放jedis 对象  
                redisClient.brokenResource(jedis);  
            }  
        }  
        return result;  
    }  
  
}  
(4),接下来要把写个具体的业务UserService,来测试redis的存储器在具体业务中的使用,即实现(非关系型数据库的持久化操作)。本例中的例子是经常项目中对user的操作

创建UserEntity实体类:

/** 
 * 用户实体类 
 * @author leo 
 * 
 */  
public class UserEntity {  
    //用户id  
    private String userId;  
    //用户账号  
    private String EmpCode;  
    //用户名称  
    private String EmpName;  
    //用户角色  
    private String role;  
    //职位  
    private String title;  
    public String getUserId() {  
        return userId;  
    }  
    public void setUserId(String userId) {  
        this.userId = userId;  
    }  
    public String getEmpCode() {  
        return EmpCode;  
    }  
    public void setEmpCode(String empCode) {  
        EmpCode = empCode;  
    }  
    public String getEmpName() {  
        return EmpName;  
    }  
    public void setEmpName(String empName) {  
        EmpName = empName;  
    }  
    public String getRole() {  
        return role;  
    }  
    public void setRole(String role) {  
        this.role = role;  
    }  
    public String getTitle() {  
        return title;  
    }  
    public void setTitle(String title) {  
        this.title = title;  
    } 
然后创建用户操作的业务层Service;由于这里主要是测试NOSQL的数据持久化,所以就忽略了对数据库持久化层(DAO)的操作。

userServiceImpl类:

/** 
 * 业务层接口实现 
 * @author leo 
 * 
 */  
public class UserServiceImpl implements IUserService {  
    private static final String  cacheKey  ="userEntity";  
    /** 
     * 缓存存储 
     */  
    private RedisCacheStorageImpl<UserEntity> storageCache;  
      
    public void setStorageCache(RedisCacheStorageImpl<UserEntity> storageCache) {  
        this.storageCache = storageCache;  
    }  
    /** 
     * 新增 
     * @param entity 
     * @return 
     */  
    @Override  
    public boolean addUserEntity(UserEntity entity) {  
        //非空  
        if(entity ==null || StringUtils.isEmpty(entity.getUserId())){  
            return false;  
        }  
        /** 
         * 做数据库持久化,这里就无需再申明了 
         */  
        System.out.println("先插入数据库中,.........");  
        //然后接下来做非关系型数据库持久化  
        return storageCache.hset(cacheKey, entity.getUserId(), entity);  
    }  
  
    @Override  
    public boolean deleteUserEntity(UserEntity entity) {  
          
        return false;  
    }  
    /** 
     * 根据id 查询 
     * @return 
     */  
    @Override  
    public UserEntity queryUserEntityByUserId(UserEntity userEntity) {  
        //非空  
        if(userEntity ==null || StringUtils.isEmpty(userEntity.getUserId())){  
            return null;  
        }  
        //先去缓存中查询 是否存在,不存在在查询  
         UserEntity reslut = storageCache.hget(cacheKey, userEntity.getUserId());  
        if(reslut!=null){  
            return reslut;  
        }else{  
            //查询数据库  
            System.out.println("查询数据库");  
        }  
        return null;  
    }  
  
}  
以及spring-bean.xml的配置对业务层的管理:
<!-- storge Cache 存储器-->  
        <bean id="storageCache" class="com.deppon.cache.storage.impl.RedisCacheStorageImpl">  
            <property name="redisClient" ref="redisClient" />  
        </bean>  
        <bean id="userServiceImpl" class="com.deppon.cache.service.impl.UserServiceImpl">  
            <property name="storageCache" ref="storageCache"/>  
        </bean>  

(6).最后写个junit 测下,查看是否有没有插入到redis库中

public class TestUserServiceImpl {  
    /**  
     * 用户接口  
     */  
    private IUserService userServiceImpl;  
      
    public void setUserServiceImpl(IUserService userServiceImpl) {  
        this.userServiceImpl = userServiceImpl;  
    }  
    @Before  
    public void setUp() throws Exception {  
        userServiceImpl = (IUserService) SpringTestHelper.get().getBeanByClass(UserServiceImpl.class);  
    }  
  
    @After  
    public void tearDown() throws Exception {  
    }  
    @Test  
    public void testAdd(){  
        UserEntity entity = new UserEntity();  
        entity.setUserId("000001");  
        entity.setEmpCode("130566");  
        entity.setEmpName("leonardo-zeng");  
        entity.setRole("Java Development Engineer");  
        entity.setTitle("PM");  
        boolean isTrue =userServiceImpl.addUserEntity(entity);  
        Assert.assertTrue(isTrue);  
    }  
      
    @Test  
    public void testQueryById(){  
        UserEntity entity = new UserEntity();  
        entity.setUserId("000001");  
        UserEntity userEntity =userServiceImpl.queryUserEntityByUserId(entity);  
        System.out.println(userEntity);  
    }  
}  
连接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就这样了






阅读更多
文章标签: Redis
个人分类: Redis
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭