1.定义读取redis配置文件的配置类RedisConfig
package MiaoSha.redis;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* Redis的配置文件
* @ConfigurationProperties(prefix="redis"),所有以reis开头的配置信息能够读取到
* @author msi
*
*/
@Component
@ConfigurationProperties(prefix="redis")
public class RedisConfig {
private String host;
private int port;
private int timeout;//秒
private String password;
private int poolMaxTotal;
private int poolMaxIdle;
private int poolMaxWait;//秒
}
2.定义返回获取连接池对象的RedisPoolFactory
package MiaoSha.redis;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
@Service
public class RedisPoolFactory {
@Autowired
RedisConfig redisConfig;
/*获取jedispool
* @return
*/
@Bean
public JedisPool JedisFactory(){
JedisPoolConfig poolConfig=new JedisPoolConfig();
poolConfig.setMaxIdle(redisConfig.getPoolMaxIdle());
poolConfig.setMaxTotal(redisConfig.getPoolMaxTotal());
poolConfig.setMaxWaitMillis(redisConfig.getPoolMaxWait()*1000);
JedisPool jp=new JedisPool(poolConfig,redisConfig.getHost(),redisConfig.getPort(),
redisConfig.getTimeout()*1000,redisConfig.getPassword(),0);
return jp;
}
}
3.定义对应redis操作get,set,exists等方法的的RedisService
package MiaoSha.redis;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson.JSON;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
@Service
public class RedisService {
@Autowired
JedisPool jedisPool;
/**通过key,获取value转换成对应的bean输出
* 先从jedisPool中获取连接,然后通过get取值,再转换,最后归还连接
* @param prefix 拼接key的前缀
* @param key
* @param clazz
* @return
*/
public <T>T get(KeyPrefix prefix,String key,Class<T>clazz){
Jedis jedis=null;
try {
jedis=jedisPool.getResource();
//生成真正的key
String realKsy=prefix.getPrefix()+key;
String str=jedis.get(realKsy);
T t=StringToBean(str,clazz);
return t;
} finally {
returnToPool(jedis);
}
}
/**
* 设置对象
* @param prefix
* @param key
* @param value
* @return
*/
public <T> boolean set(KeyPrefix prefix,String key,T value){
Jedis jedis=null;
try {
jedis=jedisPool.getResource();
String str=beanToString(value);
if(str==null||str.length()<=0){
return false;
}
//生成真正的key
String realKsy=prefix.getPrefix()+key;
//过期时间
int seconds=prefix.expireSeconds();
if(seconds<=0){
jedis.set(realKsy, str);
}else{//设置过期时间
jedis.setex(realKsy, seconds, str);
}
return true;
} finally {
returnToPool(jedis);
}
}
/**
* 判断key是否存在
* @param prefix
* @param key
* @param value
* @return
*/
public <T> boolean exists(KeyPrefix prefix,String key){
Jedis jedis=null;
try {
jedis=jedisPool.getResource();
//生成真正的key
String realKsy=prefix.getPrefix()+key;
return jedis.exists(realKsy);
} finally {
returnToPool(jedis);
}
}
/**
* 自增值
* @param prefix
* @param key
* @return
*/
public <T> Long incr(KeyPrefix prefix,String key){
Jedis jedis=null;
try {
jedis=jedisPool.getResource();
//生成真正的key
String realKsy=prefix.getPrefix()+key;
return jedis.incr(realKsy);
} finally {
returnToPool(jedis);
}
}
/**
* 减少
* @param prefix
* @param key
* @return
*/
public <T> Long decr(KeyPrefix prefix,String key){
Jedis jedis=null;
try {
jedis=jedisPool.getResource();
//生成真正的key
String realKsy=prefix.getPrefix()+key;
return jedis.decr(realKsy);
} finally {
returnToPool(jedis);
}
}
/**
* 将bean转换成string
* @param value
* @return
*/
private <T> String beanToString(T value) {
if(value==null){
return null;
}
Class<?>clazz=value.getClass();
if(clazz==int.class||clazz==Integer.class){
return ""+value;
}else if(clazz==String.class){
return (String)value;
}else if(clazz==long.class||clazz==Long.class){
return ""+value;
}else{
return JSON.toJSONString(value);
}
}
/**
* 将字符串转换成Bean对象
* @return
*/
@SuppressWarnings("unchecked")
private<T> T StringToBean(String str,Class<T> clazz) {
if(str==null||str.length()==0||clazz==null){
return null;
}
if(clazz==int.class||clazz==Integer.class){
return (T) Integer.valueOf(str);
}else if(clazz==String.class){
return (T) str;
}else if(clazz==long.class||clazz==Long.class){
return (T)Long.valueOf(str);
}else{
return JSON.toJavaObject(JSON.parseObject(str), clazz);
}
}
/**
* 归还连接
* @param jedis
*/
private void returnToPool(Jedis jedis) {
if(jedis!=null){
jedis.close();
}
}
}
4.利用模块模式定义redis的key,防止在set时,key相同导致内容覆盖
定义抽象类KeyPrefix,定义了要实现方法
package MiaoSha.redis;
public interface KeyPrefix {
public int expireSeconds();//过期时间
public String getPrefix();//前缀
}
5.定义实现该类的基类,定义所有继承自己的子类能调用的方法
package MiaoSha.redis;
public abstract class BasePrefix implements KeyPrefix{
private int expireSeconds;
private String prefix;
public BasePrefix(String prefix){//默认0,代表永不过期
this(0,prefix);
}
public BasePrefix(int expireSeconds, String prefix){
this.expireSeconds=expireSeconds;
this.prefix=prefix;
}
public int expireSeconds() {
return expireSeconds;
}
@Override
public String getPrefix() {//因为这里是基类,可以获取对应子类的类名
String className=getClass().getSimpleName();//获取类名
return className+":"+prefix;
}
}
6.定义对应的子类
1)
package MiaoSha.redis;
public class OrderKey extends BasePrefix{
public OrderKey(int expireSeconds, String prefix) {
super(expireSeconds, prefix);
}
}
2)
package MiaoSha.redis;
public class UserKey extends BasePrefix{
private UserKey( String prefix) {
super( prefix);
}
public static UserKey getById=new UserKey("id");
public static UserKey getByName=new UserKey("name");
}
实例
redisService.get(UserKey.getById,""+1,User.class);
getById得到的是id,在get方法的
String realKey=prefix.getPrefix()+key;
在prefix.getPrefix()去调用实现类BasePrefix中的方法,得到:UserKey:id
即realKey=UserKey:id+1 = UserKey:id1;
这样就保证了key的唯一