redis数据结构缓存运用

之前redis已经描述了redis 的基本作用与用处, 这一篇主要讲述redis运用场景以及分片,和spring整合。redis 存储数据结构大致5种,String 普通键值对,用的比较多。HASH针对 key 唯一标识 hashmap 键值对运用也比较多 list set 当然是集合运用 sortedSet 排序集合使用。
首先看redis 和spring 配置整合

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">

<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="order" value="2" />
<property name="ignoreUnresolvablePlaceholders" value="true" />
<property name="locations">
<list>
<value>classpath:demo-provider-module.properties</value>
</list>
</property>
</bean>
<!-- redis连接池的配置 -->
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxTotal" value="2048" />
<property name="maxIdle" value="200" />
<property name="numTestsPerEvictionRun" value="1024"/>
<property name="timeBetweenEvictionRunsMillis" value="30000" />
<property name="minEvictableIdleTimeMillis" value="-1" />
<property name="softMinEvictableIdleTimeMillis" value="10000" />
<property name="maxWaitMillis" value="1500"/>
<property name="testOnBorrow" value="true" />
<property name="testWhileIdle" value="true"/>
<property name="testOnReturn" value="false"/>
<property name="jmxEnabled" value="true"/>
<property name="jmxNamePrefix" value="youyuan"/>
<property name="blockWhenExhausted" value="false"/>
</bean>
<!-- redis的连接池pool,不是必选项:timeout/password -->
<bean id="shardedJedisPool" class="redis.clients.jedis.ShardedJedisPool">
<constructor-arg index="0" ref="jedisPoolConfig"/>
<constructor-arg index="1">
<list>
<bean name="master" class="redis.clients.jedis.JedisShardInfo">
<constructor-arg index="0" value="${redis1.server.host}"/>
<constructor-arg index="1" value="${redis1.server.port}" type="int"/><!-- 指定参数类型否则可能回报错 -->
<constructor-arg index="2" value="${redis1.server.timeout}" type="int"/>
</bean>
</list>
</constructor-arg>
</bean>
</beans>

可能开发中redis 服务器一般不止一台 在list 下注入就行。
相信很多时候我们在写代码的时候数据结构运用的恰当能够,帮我审很多事,并且解决很多问题,redis 也一样。自己封装了一下常用的redis 使用工具类

package demo.dcn.cache;

import java.util.ArrayList;
import java.util.List;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.google.protobuf.Internal.ProtobufList;
/**
* Redis序列化及反序列化工具类
* @author kun.zhang@downjoy.com
*/
public class JedisUtil {

/**
* 把对象转换成json 文本
* @param object
* @return
*/
public static String toJson(Object object){
return JSON.toJSONString(object);
}
/**
* 单独的T 代表一个类型 而 Class<T>代表这个类型所对应的类
* 把JSON文本parse为JavaBean
* @param json
* @param clazz
* @return
*/
public static <T> T toObject(String json,Class<T> clazz){
return JSON.parseObject(json, clazz);
}

/**
* 泛型解析方法
*
* @param json
* @param typeReference
* @return
*/
public static <T> T toObject(String json,TypeReference<T> typeReference){
return JSON.parseObject(json, typeReference);
}
/**
* 把json 文本转换成对象集合形式
* @param json
* @param T
* @return
*/
public static <T> List<T> parseArray(String json,Class<T> T){
return JSON.parseArray(json, T);
}
/**
* 解析数组json 转换成对象集合方式
* @param jsons
* @param clazz
* @return
*/
public static <T> List<T> toObjects(List<String> jsons, Class<T> clazz){
List<T> list = new ArrayList<T>();
for (String json : jsons) {
T obj = toObject(json, clazz);
if(null != obj) {
list.add(obj);
}
}
return list;
}

/**
* 把把JSON文本parse为JSONObject javamap或者JSONArray Javalist
* @param json
* @return
*/
public static Object parseObject(String json){
return JSON.parse(json);
}
/**
* 把JSON文本parse成JSONObject
* @param json
* @return
*/
public static JSONObject parJsonObject(String json){
return JSONObject.parseObject(json);
}

/**
* 把JSON文本parse成JSONArray
* @param text
* @return
*/
public static final JSONArray parseArray(String text){
return JSONArray.parseArray(text);
}
/**
* 将JavaBean序列化为带格式的JSON文本
* @param object
* @param prettyFormat
* @return
*/
public static final String toJSONString(Object object, boolean prettyFormat){
return JSON.toJSONString(object, prettyFormat);
}

/**
* 将JavaBean转换为JSONObject或者JSONArray
* @param javaObject
* @return
*/
public static final Object toJSON(Object javaObject){
return JSON.toJSON(javaObject);
}

}


package demo.dcn.cache;

import redis.clients.jedis.ShardedJedis;

/**
* 自定义分片jedis
* @author kun.zhang@downjoy.com
*/
public class SelfShardedJedis {

private ShardedJedis shardedJedis;//分片

private Boolean isReturn;//是否归还连接池

public SelfShardedJedis(ShardedJedis shardedJedis, Boolean isReturn) {
super();
this.shardedJedis = shardedJedis;
this.isReturn = isReturn;
}

public SelfShardedJedis() {
super();
}
/**
* @return the shardedJedis
*/
public ShardedJedis getShardedJedis() {
return shardedJedis;
}

/**
* @param shardedJedis the shardedJedis to set
*/
public void setShardedJedis(ShardedJedis shardedJedis) {
this.shardedJedis = shardedJedis;
}

/**
* @return the isReturn
*/
public Boolean getIsReturn() {
return isReturn;
}

/**
* @param isReturn the isReturn to set
*/
public void setIsReturn(Boolean isReturn) {
this.isReturn = isReturn;
}
}


package demo.dcn.cache;

import java.util.Set;

import javax.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisShardInfo;
import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.ShardedJedisPool;
public class RedisClientBase implements RedisClient {

private final Logger logger = LoggerFactory.getLogger(RedisClientBase.class);
private static final String NX ="NX";//redis 设置key不存在时候起作用
private static final String XX = "XX";//redis 设置key存在 ,才能对键进行操作
private static final String EX ="EX";//redis 设置键固定时间秒
private static final String PX ="PX";//redis 设置键固定时间毫秒

@Resource
private ShardedJedisPool shardedJedisPool;//连接池

public static final int MAX_SCAN_COUNT = 200;

private static RedisClient redisclient;

public RedisClientBase(ShardedJedisPool shardedJedisPool) {
super();
this.shardedJedisPool = shardedJedisPool;
}
public RedisClientBase() {
redisclient = this;
}
public static RedisClient getInstance() {
return redisclient;
}
/**
* 获取一个分片 jedis 客户端
*
* @return
*/
public SelfShardedJedis getShardedJedis(){
ShardedJedis shards = shardedJedisPool.getResource();
SelfShardedJedis selfShardedJedis = new SelfShardedJedis(shards, false);
return selfShardedJedis;
}

/**
* 关闭 jedis 切片池
* @param jedis
* @param broken
*/
@SuppressWarnings({ "null", "deprecation" })
public void closeRedisThread(SelfShardedJedis jedis, boolean broken){
try{
if(jedis!=null||jedis.getIsReturn()){
return;
}
if(broken){
shardedJedisPool.returnBrokenResource(jedis.getShardedJedis());
jedis.setIsReturn(true);
}else{
shardedJedisPool.returnResource(jedis.getShardedJedis());
jedis.setIsReturn(true);
}
}catch(Exception e){
logger.error(e.getMessage(),e);
}

}

/**setnx 的值设为 value ,当且仅当 key 不存在。 若给定的 key 已经存在,则 setNotExists 不做任何动作。
* 保存
* @param key
* @param obj
* @return
* 设置成功,返回 1 ;设置失败,返回 0 。
*/
public Long setNotExists(String key,byte[] obj){
SelfShardedJedis shardedJedis = null;
boolean broken = false;
try{
shardedJedis = getShardedJedis();
return shardedJedis.getShardedJedis().setnx(key.getBytes(), obj);//保存成二进制
}catch(Exception e){
logger.error(e.getMessage(), e);
broken = true;
}finally{
closeRedisThread(shardedJedis, broken);
}
return 0L;
}
/**
* 将 key 的值设为 value ,且设置过期时间,当且仅当 key 不存在。 若给定的 key 已经存在,则 setNotExists 不做任何动作。 * Set the string value as value of the key. The string
* can't be longer than 1073741824 bytes (1 GB).
* @param key
* @param value
* @param nxxx
* @param expx
* @param time
* @return
*/
public String set(String key,String value, String nxxx, String expx, long time){
SelfShardedJedis shardedJedis = null;
boolean broken = false;
try{
shardedJedis = getShardedJedis();
return shardedJedis.getShardedJedis().set(key, value, nxxx, expx, time);
}catch(Exception e){
logger.error(e.getMessage(), e);
broken = true;
} finally {
closeRedisThread(shardedJedis, broken);
}
return null;
}

/**
* 通过key 获取字符串数据
* @param key
* @return
*/
public String getString(String key){
SelfShardedJedis shardedJedis = null;
boolean broken = false;
try{
shardedJedis = getShardedJedis();
return shardedJedis.getShardedJedis().get(key);
}catch(Exception e){
logger.error(e.getMessage(), e);
broken = true;
}finally {
closeRedisThread(shardedJedis, broken);
}
return null;
}

/**
* 设置key过期时间
* @param key
* @param obj
* @param expireTime
* @return
*/
public String setExpire(String key, byte[] obj, int expireTime) {
SelfShardedJedis shardedJedis = null;
boolean broken = false;
try {
shardedJedis = getShardedJedis();
return shardedJedis.getShardedJedis().setex(key.getBytes(), expireTime, obj);
} catch (Exception e) {
logger.error(e.getMessage(), e);
broken = true;
} finally {
closeRedisThread(shardedJedis, broken);
}
return null;
}
/**
* 设置key过期时间
* @param key
* @param expireTime
* @return
*/
public Long expire(String key, int expireTime) {
SelfShardedJedis shardedJedis = null;
boolean broken = false;
try {
shardedJedis = getShardedJedis();
return shardedJedis.getShardedJedis().expire(key, expireTime);
} catch (Exception e) {
logger.error(e.getMessage(), e);
broken = true;
} finally {
closeRedisThread(shardedJedis, broken);
}
return null;
}

/**
* 移除有序集 key 中,指定排名(rank)区间内的所有成员。
* <p/>
* 区间分别以下标参数 start 和 stop 指出,包含 start 和 stop 在内。 下标参数 start 和 stop 都以 0 为底,也就是说,以 0 表示有序集第一个成员,以 1 表示有序集第二个成员,以此类推。 你也可以使用负数下标,以 -1
* 表示最后一个成员, -2 表示倒数第二个成员,以此类推
*
* @param key
* @param start
* @param stop
* @return
*/
public Long zremrangeByRank(String key, long start, long stop) {
long result = 0L;
SelfShardedJedis shardedJedis = null;
boolean broken = false;
try {
shardedJedis = getShardedJedis();
result = shardedJedis.getShardedJedis().zremrangeByRank(key, start, start);
} catch (Exception e) {
broken = true;
logger.error(e.getMessage(), e);
} finally {
closeRedisThread(shardedJedis, broken);
}
return result;
}

/**
* 返回有序集 key 中,指定区间内的成员 其中成员的位置按 score 值递减(从大到小)来排列
*
* @param key
* @param start
* @param stop
* @return
*/
public Set<String> zrevrange(String key, long start, long stop) {
Set<String> result = null;
SelfShardedJedis shardedJedis = null;
boolean broken = false;
try {
shardedJedis = getShardedJedis();
result = shardedJedis.getShardedJedis().zrevrange(key, start, start);
} catch (Exception e) {
broken = true;
logger.error(e.getMessage(), e);
} finally {
closeRedisThread(shardedJedis, broken);
}
return result;
}


/**
* 删除key
* @param key
* @return
*/
public Long del(String key) {
SelfShardedJedis shardedJedis = null;
boolean broken = false;
try {
shardedJedis = getShardedJedis();
return shardedJedis.getShardedJedis().del(key);
} catch (Exception e) {
broken = true;
logger.error(e.getMessage(), e);
} finally {
closeRedisThread(shardedJedis, broken);
}
return null;
}

/**
* 计数器
*
* @param key
* @param seconds 过期时间长度,单位:秒;值为0或负数表示不过期。
* @param roll 时间是否滚动
*/
public Long incr(String key, int seconds, boolean roll) {
long b = 0;
SelfShardedJedis shardedJedis = null;
boolean broken = false;
try {
shardedJedis = getShardedJedis();
b = shardedJedis.getShardedJedis().incr(key.getBytes());
if (seconds > 0) {
if (b == 1) {// 第一次进入,设置过期时间
shardedJedis.getShardedJedis().expire(key.getBytes(), seconds);
}
if (roll && b > 1) {// 时间滚动
shardedJedis.getShardedJedis().expire(key.getBytes(), seconds);
}
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
broken = true;
} finally {
if (broken && shardedJedis != null) {
shardedJedis.getShardedJedis().del(key);
}
closeRedisThread(shardedJedis, broken);
}
return b;
}
/**
* 判断key 是否存在
* @param key
* @return若
*/
public Boolean exists(String key) {
SelfShardedJedis shardedJedis = null;
boolean broken = false;
try {
shardedJedis = getShardedJedis();
return shardedJedis.getShardedJedis().exists(key.getBytes());
} catch (Exception e) {
logger.error(e.getMessage(), e);
broken = true;
} finally {
closeRedisThread(shardedJedis, broken);
}
return false;
}


/**
* 通过key 获取 jedis
* @param key
* @return
*/

public Jedis getShard(String key) {
SelfShardedJedis shardedJedis = null;
boolean broken = false;
try {
shardedJedis = getShardedJedis();
if (shardedJedis != null) {
return shardedJedis.getShardedJedis().getShard(key);
}
} catch (Exception e) {
e.printStackTrace();
logger.error(e.getMessage(), e);
broken = true;
} finally {
closeRedisThread(shardedJedis, broken);
}
return null;
}

/**
* 获取JedisShardInfo
*
* @param key
* @return JedisShareInfo
*/
public JedisShardInfo getShardInfo(String key) {
SelfShardedJedis shardedJedis = null;
boolean broken = false;
try {
shardedJedis = getShardedJedis();
if (shardedJedis != null) {
return shardedJedis.getShardedJedis().getShardInfo(key);
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
broken = true;
} finally {
closeRedisThread(shardedJedis, broken);
}
return null;
}
/**
* 保存字符串键值对
* @param key
* @param value
* @return
*/
public String set(String key, String value) {
SelfShardedJedis shardedJedis = null;
boolean broken = false;
try {
shardedJedis = getShardedJedis();
if (shardedJedis != null) {
return shardedJedis.getShardedJedis().set(key, value);
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
broken = true;
} finally {
closeRedisThread(shardedJedis, broken);
}
return null;
}
/**
* 获取key的类型
* @param key
* @return
*/
public String type(String key) {
SelfShardedJedis shardedJedis = null;
boolean broken = false;
try {
shardedJedis = getShardedJedis();
if (shardedJedis != null) {
return shardedJedis.getShardedJedis().type(key);
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
broken = true;
} finally {
closeRedisThread(shardedJedis, broken);
}
return null;
}

/**
* 获取key 剩余时间 当 key 不存在时,返回 -2 。
* 当 key 存在但没有设置剩余生存时间时,返回 -1 。
* 否则,以秒为单位,返回 key 的剩余生存时间。
* @param key
* @return
*/
public Long ttl(String key) {
SelfShardedJedis shardedJedis = null;
boolean broken = false;
try {
shardedJedis = getShardedJedis();
if (shardedJedis != null) {
return shardedJedis.getShardedJedis().ttl(key);
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
broken = true;
} finally {
closeRedisThread(shardedJedis, broken);
}
return null;
}

/**
* 为key 设定一个新值,并返回旧值
* 返回给定 key 的旧值。
* 当 key 没有旧值时,也即是, key 不存在时,返回 nil 。 不是字符串类型返回错误
* @param key
* @param value
* @return
*/
public String getSet(String key, String value) {
SelfShardedJedis shardedJedis = null;
boolean broken = false;
try {
shardedJedis = getShardedJedis();
if (shardedJedis != null) {
return shardedJedis.getShardedJedis().getSet(key, value);
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
broken = true;
} finally {
closeRedisThread(shardedJedis, broken);
}
return null;
}
/**
* 当key 不存在时候 保存key String类型 存在不做什么操作返回0
* @param key
* @param value
* @return
*/
public Long setnx(String key, String value) {
SelfShardedJedis shardedJedis = null;
boolean broken = false;
try {
shardedJedis = getShardedJedis();
if (shardedJedis != null) {
return shardedJedis.getShardedJedis().setnx(key, value);
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
broken = true;
} finally {
closeRedisThread(shardedJedis, broken);
}
return null;
}
/**
* 设置key 存在修改,不存在保存
* @param key
* @param seconds
* @param value
* @return
*/
public String setex(String key, int seconds, String value) {
SelfShardedJedis shardedJedis = null;
boolean broken = false;
try {
shardedJedis = getShardedJedis();
if (shardedJedis != null) {
return shardedJedis.getShardedJedis().setex(key, seconds, value);
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
broken = true;
} finally {
closeRedisThread(shardedJedis, broken);
}
return null;
}

/**
* 对指定的key 进行减少 如果key 不存在 key值会被初始化0 然后减少
* @param key
* @param integer
* @return
*/
public Long decrBy(String key, long integer) {
SelfShardedJedis shardedJedis = null;
boolean broken = false;
try {
shardedJedis = getShardedJedis();
if (shardedJedis != null) {
return shardedJedis.getShardedJedis().decrBy(key, integer);
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
broken = true;
} finally {
closeRedisThread(shardedJedis, broken);
}
return null;
}
/**
* 如果key 按指定增量增加 key 不存在 创造key 初始化为0 incr 自增为1
* @param key
* @param integer
* @return
*/
public Long incrBy(String key, long integer) {
SelfShardedJedis shardedJedis = null;
boolean broken = false;
try {
shardedJedis = getShardedJedis();
if (shardedJedis != null) {
return shardedJedis.getShardedJedis().incrBy(key, integer);
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
broken = true;
} finally {
closeRedisThread(shardedJedis, broken);
}
return null;
}
/**
* 为已经存在的key追加新值,返回 长度 如果key 不存在,直接设置key为value
* @param key
* @param value
* @return
*/
public Long append(String key, String value) {
SelfShardedJedis shardedJedis = null;
boolean broken = false;
try {
shardedJedis = getShardedJedis();
if (shardedJedis != null) {
return shardedJedis.getShardedJedis().append(key, value);
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
broken = true;
} finally {
closeRedisThread(shardedJedis, broken);
}
return null;
}

/**
* 截取字符串
* @param key
* @param start
* @param end
* @return
*/
public String substr(String key, int start, int end) {
SelfShardedJedis shardedJedis = null;
boolean broken = false;
try {
shardedJedis = getShardedJedis();
if (shardedJedis != null) {
return shardedJedis.getShardedJedis().substr(key, start, end);
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
broken = true;
} finally {
closeRedisThread(shardedJedis, broken);
}
return null;
}
}


这里主要是针对String类型 封装的方法 ,其他类型基本大致一直。可以对照着网站去理解,

这里的json输出, 序列化 是用的阿里巴巴fastjson,也可以Google gson, protobuf 在序列化方面是比较快的。找时间试一试。
[url]http://redisdoc.com/index.html[/url]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值