1.Redis 安装
Window 下安装
下载地址:https://github.com/MSOpenTech/redis/releases。
Redis 支持 32 位和 64 位。这个需要根据你系统平台的实际情况选择,这里我们下载 Redis-x64-xxx.zip压缩包到 C 盘,解压后,将文件夹重新命名为 redis。
Windows环境安装redis途中遇到的问题:
https://www.cnblogs.com/javabg/p/9133206.html
2.集成Redis
Jedis :jedis就是集成了redis的一些命令操作,封装了redis的java客户端。提供了连接池管理。一般不直接使用jedis,而是在其上在封装一层,作为业务的使用。
- 添加Jedis依赖
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.7.3</version>
</dependency>
- 添加Fastjson依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.38</version>
</dependency>
- 添加redis的配置项
redis.host=127.0.0.1
redis.port=6379
redis.timeout=10
redis.password=123456
redis.poolMaxTotal=1000
redis.poolMaxldle=500
redis.poolMaxWait=500
- 新建一个包redis,在里面新建一个RedisConfig类。
@Component
@ConfigurationProperties(prefix="redis")//将application.properties里面前缀redis都读取
public class RedisConfig {
private String host;
private int port;
private int timeout;
private String password;
private int poolMaxTotal;
private int poolMaxldle;
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 getPoolMaxldle() {
return poolMaxldle;
}
public void setPoolMaxldle(int poolMaxldle) {
this.poolMaxldle = poolMaxldle;
}
public int getPoolMaxWait() {
return poolMaxWait;
}
public void setPoolMaxWait(int poolMaxWait) {
this.poolMaxWait = poolMaxWait;
}
}
注意:@ConfigurationProperties(prefix=“redis”)指定配置文件里面前缀为”redis”的配置项,与配置项里面的属性对应起来。
- 再在redis包中创建RedisPoolFactory类,RedisPoolFactory 通过配置文件,生成Jedis连接池(配置),方便在RedisService中调用。
@Service
public class RedisPoolFactory {
@Autowired
RedisConfig redisConfig;
//JedisPool的实例注入到spring容器里面
@Bean
public JedisPool JedisPoolFactory() {
JedisPoolConfig poolConfig=new JedisPoolConfig();
System.out.println("redisConfig.getPoolMaxldle():"+redisConfig.getPoolMaxldle());
System.out.println("redisConfig.getPoolMaxTotal():"+redisConfig.getPoolMaxTotal());
System.out.println("redisConfig.getPoolMaxWait():"+redisConfig.getPoolMaxWait());
System.out.println("redisConfig.getPassword():"+redisConfig.getPassword());
poolConfig.setMaxIdle(redisConfig.getPoolMaxldle());
poolConfig.setMaxTotal(redisConfig.getPoolMaxTotal());
poolConfig.setMaxWaitMillis(redisConfig.getPoolMaxWait()*1000);//s-->ms
//因为我们使用的是s(秒)来配置的,而源码使用的是ms(毫秒),所以转换一下
JedisPool jp=new JedisPool(poolConfig,redisConfig.getHost(),redisConfig.getPort(),
redisConfig.getTimeout()*1000,redisConfig.getPassword(),0);
return jp;
}
}
注意:RedisPoolFactory 通过配置文件,生成Jedis连接池(配置),方便在RedisService中调用。
- 再在redis包中创建RedisService类来提供所有关于redis的服务方法。
@Service
public class RedisService {
@Autowired
JedisPool jedisPool; //会出现循环依赖---Circular reference
//RedisService引用JedisPool--JedisPool在RedisService,只有创建RedisService的实例才可以获取JedisPool的bean
//所以需要单独拿出JedisPool的bean
/**
* 获取单个对象
* @param prefix
* @param key
* @param data
* @return
*/
public <T> T get(KeyPrefix prefix,String key,Class<T> data){
System.out.println("@RedisService-REDIES-GET!");
Jedis jedis=null;
//在JedisPool里面取得Jedis
try {
jedis=jedisPool.getResource();
//生成真正的key className+":"+prefix; BasePrefix:id1
String realKey=prefix.getPrefix()+key;
System.out.println("@RedisService-get-realKey:"+realKey);
//System.out.println("jedis:"+jedis);
String sval=jedis.get(realKey);
System.out.println("@RedisService-getvalue:"+sval);
//将String转换为Bean入后传出
T t=stringToBean(sval,data);
return t;
}finally {
returnToPool(jedis);
}
}
/**
* 移除对象,删除
* @param prefix
* @param key
* @return
*/
public boolean delete(KeyPrefix prefix,String key){
Jedis jedis=null;
try {
jedis=jedisPool.getResource();
String realKey=prefix.getPrefix()+key;
long ret=jedis.del(realKey);
return ret>0;//删除成功,返回大于0
//return jedis.decr(realKey);
}finally {
returnToPool(jedis);
}
}
/**
* 设置单个、多个对象
* @param prefix
* @param key
* @param value
* @return
*/ //MiaoshaUserKey.token, token, user
public <T> boolean set(KeyPrefix prefix,String key,T value){
System.out.println("@RedisService-REDIES-SET!");
Jedis jedis=null;
try {//在JedisPool里面取得Jedis
jedis=jedisPool.getResource();
String realKey=prefix.getPrefix()+key;
System.out.println("@RedisService-key:"+key);
System.out.println("@RedisService-getPrefix:"+prefix.getPrefix());
//System.out.println("set-realKey:"+realKey);
String s=beanToString(value);//将T类型转换为String类型,json类型??
//System.out.println("s:"+s);
if(s==null||s.length()<=0) {
return false;
}
int seconds=prefix.expireSeconds();
if(seconds<=0) {//有效期:代表不过期,这样才去设置
jedis.set(realKey, s);
//System.out.println("1");
}else {//没有设置过期时间,即没有设置有效期,那么自己设置。
jedis.setex(realKey, seconds,s);
//System.out.println("2");
}
return true;
}finally {
returnToPool(jedis);
//System.out.println("3");
}
}
/**
* 减少值
* @param prefix
* @param key
* @return
*/
public <T> Long decr(KeyPrefix prefix,String key){
Jedis jedis=null;
try {
jedis=jedisPool.getResource();
String realKey=prefix.getPrefix()+key;
return jedis.decr(realKey);
}finally {
returnToPool(jedis);
}
}
/**
* 增加值
* @param prefix
* @param key
* @return
*/
public <T> Long incr(KeyPrefix prefix,String key){
Jedis jedis=null;
try {
jedis=jedisPool.getResource();
String realKey=prefix.getPrefix()+key;
return jedis.incr(realKey);
}finally {
returnToPool(jedis);
}
}
/**
* 检查key是否存在
* @param prefix
* @param key
* @return
*/
public <T> boolean exitsKey(KeyPrefix prefix,String key){
Jedis jedis=null;
try {
jedis=jedisPool.getResource();
String realKey=prefix.getPrefix()+key;
return jedis.exists(realKey);
}finally {
returnToPool(jedis);
}
}
/**
* 将字符串转换为Bean对象
*
* parseInt()返回的是基本类型int 而valueOf()返回的是包装类Integer
* Integer是可以使用对象方法的 而int类型就不能和Object类型进行互相转换 。
* int a=Integer.parseInt(s);
Integer b=Integer.valueOf(s);
*/
public static <T> T stringToBean(String s,Class<T> clazz) {
if(s==null||s.length()==0||clazz==null) {
return null;
}
if(clazz==int.class||clazz==Integer.class) {
return ((T) Integer.valueOf(s));
}else if(clazz==String.class) {
return (T) s;
}else if(clazz==long.class||clazz==Long.class) {
return (T) Long.valueOf(s);
}else {
JSONObject json=JSON.parseObject(s);
return JSON.toJavaObject(json, clazz);
}
}
/**
* 将Bean对象转换为字符串类型
* @param <T>
*/
public static <T> String beanToString(T value) {
//如果是null
if(value==null) return null;
//如果不是null
Class<?> clazz=value.getClass();
if(clazz==int.class||clazz==Integer.class) {
return ""+value;
}else if(clazz==String.class) {
return ""+value;
}else if(clazz==long.class||clazz==Long.class) {
return ""+value;
}else {
return JSON.toJSONString(value);
}
}
private void returnToPool(Jedis jedis) {
if(jedis!=null) {
jedis.close();
}
}
public <T> boolean set(String key,T value){
Jedis jedis=null;
//在JedisPool里面取得Jedis
try {
jedis=jedisPool.getResource();
//将T类型转换为String类型
String s=beanToString(value);
if(s==null) {
return false;
}
jedis.set(key, s);
return true;
}finally {
returnToPool(jedis);
}
}
public <T> T get(String key,Class<T> data){
Jedis jedis=null;
//在JedisPool里面取得Jedis
try {
jedis=jedisPool.getResource();
System.out.println("jedis:"+jedis);
String sval=jedis.get(key);
System.out.println("sval:"+sval);
//将String转换为Bean入后传出
T t=stringToBean(sval,data);
return t;
}finally {
returnToPool(jedis);
}
}
}
注意:该类中封装了常用的Redis 方法操作。
- public T get(KeyPrefix prefix,String key,Class data) 根据key取得缓存中值(根据传入的前缀)
- public boolean delete(KeyPrefix prefix,String key) 删除key
- public boolean set(KeyPrefix prefix,String key,T value) 根据key设置缓存中值
- public Long decr(KeyPrefix prefix,String key) 自减
- public Long incr(KeyPrefix prefix,String key) 自增
- public boolean exitsKey(KeyPrefix prefix,String key) 是否存在key
- public static T stringToBean(String s,Class clazz)
- public static String beanToString(T value)
但是其中,存入redis 的是String类型,这个时候我们的数据不一定是String类型,所以需要类型转换,将数据转换成String格式存入。
BeanToString()这个方法,就是来转化,先获取传入数据的Class类型,根据类型判断,int,long,String 类型,通过API转换直接转换成String即可,或是其他的自定义对象,则利用fastjson库将我们项目中定义的JavaBean 对象,转化为json字符串。
StringToBean() 相当于上个是反方法。都需要传入一个类型,这样才知道将字符串转换为什么对象。