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;
}
}