1.配置依赖
Jedis :jedis就是集成了redis的一些命令操作,封装了redis的java客户端。提供了连接池管理。一般不直接使用jedis,而是在其上在封装一层,作为业务的使用。
该项目就是在Jedis提供的操作基础上,封装了一层业务层操作。
主要几个类:1.RedisConfig RedisPoolFactory 2.RedisService
1.RedisConfig :配置Redis连接的相关属性
@Component /*该注释为了扫描进入 spring 将其视为组件*/ @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;//秒 public String getHost() { return host; } public void setHost(String host) { this.host = host; } public int getPort() { return port; } public void setPort(int port) { this.port = port; } public int getTimeout() { return timeout; } public void setTimeout(int timeout) { this.timeout = timeout; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public int getPoolMaxTotal() { return poolMaxTotal; } public void setPoolMaxTotal(int poolMaxTotal) { this.poolMaxTotal = poolMaxTotal; } public int getPoolMaxIdle() { return poolMaxIdle; } public void setPoolMaxIdle(int poolMaxIdle) { this.poolMaxIdle = poolMaxIdle; } public int getPoolMaxWait() { return poolMaxWait; } public void setPoolMaxWait(int poolMaxWait) { this.poolMaxWait = poolMaxWait; } }
RedisPoolFactory 通过配置文件,生成Jedis连接池(配置),方便在RedisService中调用。
@Service public class RedisPoolFactory { @Autowired RedisConfig redisConfig; /* 配置通过配置文件 生成配置一个 Bean 连接池对象 */ @Bean public JedisPool JedisPoolFactory(){ JedisPoolConfig poolConfig = new JedisPoolConf。ig(); poolConfig.setMaxTotal(redisConfig.getPoolMaxTotal()); poolConfig.setMaxIdle(redisConfig.getPoolMaxIdle()); poolConfig.setMaxWaitMillis(redisConfig.getPoolMaxWait()); JedisPool jedisPool = new JedisPool(poolConfig,redisConfig.getHost(),redisConfig.getPort(), redisConfig.getTimeout()*1000,redisConfig.getPassword()); return jedisPool; } }
3 RedisService
/** 通过一个RedisService 提供service 服务 * */ @Service public class RedisService { @Autowired JedisPool jedisPool; //注入连接池 /** * 通过Jedis 获取 数据 1.通过配置建立连接池 2.从连接池中拿取jedis * @param key 想要获取的数据的键 * @param clazz * @param <T> 类型 */ public <T> T get(BasePrefix prefix, String key, Class<T> clazz) { /**1.获取jedis 客户端 是一个连接,用完必须释放掉 close()方法 返回 连接池 而不是关闭 * */ Jedis jedis = null; try { jedis = jedisPool.getResource();/*调用jedisPool 对象的 getResource()方法 难道 jedis (其实就是一个连接)*/ /* 生成 新的 带有前缀的 Key*/ String realKey = prefix.getPrefix() +key; /* 通过 jedis get() 方法 通过key 获取到 值*/ String str = jedis.get(realKey); /*但我们需要的是 T 类型 通过 stringToBean 方法将str 类型转化为T 类型 */ T t = stringToBean(str,clazz); return t; }finally { returnToPool(jedis); } } /** * 删除缓存 * @param prefix * @param key * @return */ public boolean delete(BasePrefix prefix, String key) { Jedis jedis = null; try { jedis = jedisPool.getResource();/*调用jedisPool 对象的 getResource()方法 难道 jedis (其实就是一个连接)*/ /* 生成 新的 带有前缀的 Key*/ String realKey = prefix.getPrefix() +key; /* 调用jedis方法删除 缓存*/ long ret = jedis.del(realKey);//删除 行数 return ret > 0; }finally { returnToPool(jedis); } } /** * 判断KEY是否存在 * @param prefix * @param key * @return */ public boolean exist(BasePrefix prefix, String key) { /**1.获取jedis 客户端 是一个连接,用完必须释放掉 close()方法 返回 连接池 而不是关闭 * */ Jedis jedis = null; try { jedis = jedisPool.getResource();/*调用jedisPool 对象的 getResource()方法 难道 jedis (其实就是一个连接)*/ /* 生成 新的 带有前缀的 Key*/ String realKey = prefix.getPrefix() +key; /* 判断该 key 是否存在*/ return jedis.exists(realKey); }finally { returnToPool(jedis); } } /** * 键自增 * @param prefix * @param key * @param clazz * @param <T> * @return */ public <T> Long incr(BasePrefix prefix, String key) { /**1.获取jedis 客户端 是一个连接,用完必须释放掉 close()方法 返回 连接池 而不是关闭 * */ Jedis jedis = null; try { jedis = jedisPool.getResource();/*调用jedisPool 对象的 getResource()方法 难道 jedis (其实就是一个连接)*/ /* 生成 新的 带有前缀的 Key*/ String realKey = prefix.getPrefix() +key; /* 判断该 key 是否存在*/ return jedis.incr(realKey); }finally { returnToPool(jedis); } } /** * 键自减1 * @param prefix * @param key * @return */ public Long decr(BasePrefix prefix, String key) { /**1.获取jedis 客户端 是一个连接,用完必须释放掉 close()方法 返回 连接池 而不是关闭 * */ Jedis jedis = null; try { jedis = jedisPool.getResource();/*调用jedisPool 对象的 getResource()方法 难道 jedis (其实就是一个连接)*/ /* 生成 新的 带有前缀的 Key*/ String realKey = prefix.getPrefix() +key; /* 判断该 key 是否存在*/ return jedis.decr(realKey); }finally { returnToPool(jedis); } } /** * set 方法 返回类型 为boolean 成功设置还是失败 * @param key 想要获取的数据的键 * @param <T> */ public <T> boolean set(BasePrefix prefix,String key, T value) { Jedis jedis = null; try { jedis = jedisPool.getResource();/*调用jedisPool 对象的 getResource()方法 难道 jedis (其实就是一个连接)*/ /* 通过 jedis set() 方法 设置 值 * 但是 redis 只能存储 String 类型 或其他 不能存储 T 类型 需要转化 将T 类型 转化为String */ String str = beanToString(value); /* 生成 新的 带有前缀的 Key*/ String realKey = prefix.getPrefix() +key; /* 若数据为 空直接返回 false */ if (str == null) return false; int seconds = prefix.expireSeconds(); if (seconds <= 0){ /*有效期小于0 时,调用set函数 认为 永不过期*/ jedis.set(realKey,str); }else { /*当有效期不小于0,设置有效期*/ jedis.setex(realKey,seconds,str); } return true; }finally { returnToPool(jedis); } } /** 为了存储到redis中 将传入的不同类型的数据转化为String * */ public static <T> String beanToString(T value) { /*判断value的类型 并进行转化*/ if (value == null){ return null; } Class<?> clazz = value.getClass(); if (clazz == int.class || clazz ==Integer.class) { return ""+value; }else if (clazz == long.class || clazz == Long.class) { return ""+value; }else if (clazz == String.class){ return (String)value; }else { /*其他类型 默认为Bean对象 利用JSON 转化为json 串*/ /*利用阿里的 库 fastjson 将对象转化为 json 串 序列化和反序列化*/ return JSON.toJSONString(value); } } /* 将 字符串转化为 Bean 的方法*/ /** * * @param str * @param clazz 想要转化的 类型 * @param <T> * @return */ public static <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 == long.class || clazz == Long.class) { return (T) Long.valueOf(str); }else if (clazz == String.class){ return (T) str; }else { /*利用阿里的 库 fastjson 将 字符串转化为 对象的java 对象 */ return JSON.toJavaObject(JSON.parseObject(str),clazz); } } /* 将该 连接释放 重新放入连接池 */ private void returnToPool(Jedis jedis) { if (jedis!= null) { jedis.close(); } } }
该类中封装了常用的Redis 方法操作,get() set() incr() 自增,decr() 自减以及 业务需要 StringToBean() BeanToString() 等方法。
get(),set() 就是 根据传入的前缀,key存取 缓存中的数据。
但是其中,存入redis 的是String类型,这个时候我们的数据不一定是String类型,所以需要类型转换,将数据转换成String格式存入。
BeanToString()这个方法,就是来转化,先获取传入数据的Class类型,根据类型判断,int,long,String 类型,通过API转换直接转换成String即可,或是其他的自定义对象,则利用fastjson库将我们项目中定义的JavaBean 对象,转化为json字符串。
StringToBean() 相当于 上个是反方法。都需要传入一个类型,这样才知道将字符串转换为什么对象。