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就这样了




  • 99
    点赞
  • 98
    收藏
    觉得还不错? 一键收藏
  • 24
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 24
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值