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() 相當於上個是反方法。都需要傳入一個類型,這樣才知道將字符串轉換爲什麼對象。