redis使用入門介紹
本文以IDEA爲例簡單介紹redis及jedis的配置及使用說明。
一、IDEA導入相關依賴
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
二、配置文件中配置redis
本例配置文件爲application.properties
redis.host=127.0.0.1
redis.port=6379
redis.timeout=10
redis.poolMaxTotal=1000
redis.poolMaxIdle=500
redis.poolMaxWait=500
三、在實體類中讀取配置文件中redis的配置信息
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* 讀取配置文件中關於redis的配置信息
*/
@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 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;
}
}
四、自定義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;
/**
* 自定義redis連接池JedisPool,並注入spring容器
*/
@Service
public class RedisPoolFactory {
@Autowired
RedisConfig redisConfig;
/**
* 將redis連接池注入spring容器
* @return
*/
@Bean
public JedisPool JedisPoolFactory(){
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxIdle(redisConfig.getPoolMaxIdle());
config.setMaxTotal(redisConfig.getPoolMaxTotal());
config.setMaxWaitMillis(redisConfig.getPoolMaxWait() * 1000);
// 連接池參數設置
JedisPool jp = new JedisPool(config, redisConfig.getHost(), redisConfig.getPort(),
redisConfig.getTimeout()*1000, redisConfig.getPassword(), 0);
return jp;
}
}
五、redis過期時間及前綴的定義
- 先定義一個接口
/**
*包含方法:
* 有效期
* 獲取前綴
*/
public interface KeyPrefix {
/**
* 有效期
* @return
*/
public int expireSeconds();
/**
* 前綴
* @return
*/
public String getPrefix();
}
- 實現接口
public abstract class BasePrefix implements KeyPrefix {
private int expireSeconds; //過期時間
private String prefix; //前綴
public BasePrefix(String prefix){
this(0, prefix);//默認0代表永不過期
}
public BasePrefix(int expireSeconds, String prefix){
this.expireSeconds = expireSeconds;
this.prefix = prefix;
}
@Override
public int expireSeconds() {
return expireSeconds;
}
@Override
public String getPrefix() {
String className = getClass().getSimpleName();//拿到參數類類名
return className + ":" + prefix;
}
}
六、自定義redis的服務
import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
/**
* redis服務
*/
@Service
public class RedisService {
@Autowired
JedisPool jedisPool;
/**
* 從redis連接池獲取redis實例
*/
public <T> T get(KeyPrefix prefix, String key, Class<T> clazz) {
Jedis jedis = null;
try {
jedis = jedisPool.getResource(); // 從連接池中獲取一個jedis連接
//對key增加前綴,即可用於分類,也避免key重複
String realKey = prefix.getPrefix() + key; // 類名+key
String str = jedis.get(realKey);
T t = stringToBean(str, clazz);
return t;
} finally {
returnToPool(jedis);
}
}
/**
* 存儲對象
*/
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;
}
String realKey = prefix.getPrefix() + key;
int seconds = prefix.expireSeconds();//獲取過期時間
if (seconds <= 0) {
jedis.set(realKey, str);
} else {
jedis.setex(realKey, seconds, str);
}
return true;
} finally {
returnToPool(jedis); //使用結束,將jedis返回連接池
}
}
/**
* 刪除
*/
public boolean delete(KeyPrefix prefix, String key) {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
//生成真正的key
String realKey = prefix.getPrefix() + key;
long ret = jedis.del(realKey); // 如果刪除了一個或多個鍵,則爲大於0的整數,如果指定的鍵不存在,則爲0
return ret > 0; // 測試是否刪除成功,刪除成功返回true
} finally {
returnToPool(jedis); // 使用結束,將jedis返回連接池
}
}
/**
* 判斷key是否存在
*/
public <T> boolean exists(KeyPrefix prefix, String key) {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
//生成真正的key
String realKey = prefix.getPrefix() + key;
return jedis.exists(realKey); // 判斷是否已經存在key
} finally {
returnToPool(jedis); // 使用結束,將jedis返回連接池
}
}
/**
* 增加值
* Redis Incr 命令將 key 中儲存的數字值增一。 如果 key 不存在,那麼 key 的值會先被初始化爲 0 ,然後再執行 INCR 操作
*/
public <T> Long incr(KeyPrefix prefix, String key) {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
//生成真正的key
String realKey = prefix.getPrefix() + key;
return jedis.incr(realKey);
} finally {
returnToPool(jedis);
}
}
/**
* 減少值
*/
public <T> Long decr(KeyPrefix prefix, String key) {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
//生成真正的key
String realKey = prefix.getPrefix() + key;
return jedis.decr(realKey);
} finally {
returnToPool(jedis);
}
}
public static <T> String beanToString(T value) {
if (value == null) {
return null;
}
Class<?> clazz = value.getClass();
if (clazz == int.class || clazz == Integer.class) {
return String.valueOf(value);
} else if (clazz == long.class || clazz == Long.class) {
return String.valueOf(value);
} else if (clazz == String.class) {
return (String) value;
} else {
return JSON.toJSONString(value);
}
}
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 {
return JSON.toJavaObject(JSON.parseObject(str), clazz);
}
}
/**
* 作用://將jedis返回到連接池中,目的是節省jedis資源
* @param jedis
*/
private void returnToPool(Jedis jedis) {
if (jedis != null) {
jedis.close();
}
}
}
七、使用示例
import com.alibaba.druid.util.StringUtils;
import com.jesper.seckill.bean.User;
import com.jesper.seckill.exception.GlobalException;
import com.jesper.seckill.mapper.UserMapper;
import com.jesper.seckill.redis.RedisService;
import com.jesper.seckill.redis.UserKey;
import com.jesper.seckill.result.CodeMsg;
import com.jesper.seckill.util.MD5Util;
import com.jesper.seckill.util.UUIDUtil;
import com.jesper.seckill.vo.LoginVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
/**
* 關於用戶的操作
*/
@Service
public class UserService {
@Autowired
UserMapper userMapper;
@Autowired
RedisService redisService;
public static final String COOKIE_NAME_TOKEN = "token";
/**
* 由id獲取對應的用戶
* @param id
* @return
*/
public User getById(long id) {
//先從redis緩存中獲取用戶對象
User user = redisService.get(UserKey.getById, "" + id, User.class);
if (user != null) {
return user;
}
// redis緩存中不存在用戶對象,從數據庫中取
user = userMapper.getById(id);
//再存入緩存
if (user != null) {
redisService.set(UserKey.getById, "" + id, user);
}
return user;
}
}