springboot使用redis的两种方式
redis的使用真的就是使用模板存取吗? 幼稚,那要增减呢!
所以今天聊聊redis的springbooot的两种使用方法。
一、采用redisTemplate
它不是简单的引入模板就可以的,需要封装。因为模板仅仅可以操作字符串,配置redistemplate的序列化方式之后就可以顺利的执行increment、decrement。
①导包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
②配置(需要配置密码的自己配置)
spring:
redis:
host: localhost
port: 6379
③封装类
@Component
@Slf4j
public class RedisService {
@Autowired
protected RedisTemplate redisTemplate;
/**
* 配置redistemplate的序列化方式之后就可以顺利的执行increment、decrement
* @param redisTemplate
*/
@Autowired(required = false)
public void setRedisTemplate(RedisTemplate redisTemplate) {
//序列化为String
RedisSerializer stringSerializer = new StringRedisSerializer();
//序列化为Json
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer =
new Jackson2JsonRedisSerializer(Object.class);
redisTemplate.setKeySerializer(stringSerializer);
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.setHashKeySerializer(stringSerializer);
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
this.redisTemplate = redisTemplate;
}
/**
* 对字符串的操作,存入key
* @param key
* @param value
* @return
*/
public boolean setString(String key,String value){
boolean state = true;
try{
redisTemplate.opsForValue().set(key,value);
}catch (Exception e){
state = false;
log.info("redis string type,set error,key:"+key+",value:"+value+",msg:"+e.getMessage());
}
return state;
}
/**
* 对字符串的操作,获取key
* @param key
* @return
*/
public String getString(String key){
try{
Object data = redisTemplate.opsForValue().get(key);
return String.valueOf(data);
}catch (Exception e){
log.info("redis string type,get error,key:"+key+",msg:"+e.getMessage());
}
return null;
}
/**
* 给key指定过期时间
* @param key
* @param expire
* @return
*/
public boolean expire(final String key, long expire) {
boolean state = true;
try{
redisTemplate.expire(key, expire, TimeUnit.SECONDS);
}catch (Exception e){
state = false;
log.info("redis string type,set error,key:"+key+",value:"+expire+",msg:"+e.getMessage());
}
return state;
}
/**
* 给key赋值为Map类型的value
* @param key
* @param value
* @return
*/
public boolean setMap(String key, Map value) {
boolean state = true;
try {
redisTemplate.opsForHash().putAll(key, value);
} catch (Exception e) {
state = false;
log.info("redis string type,set error,key:" + key + ",value:" + value + ",msg:" + e.getMessage());
}
return state;
}
/**
* 获取key对应的值是一个Map
* @param key
* @return
*/
public Map getMap(String key) {
try {
return redisTemplate.opsForHash().entries(key);
} catch (Exception e) {
log.info("redis string type,get error,key:" + key + ",msg:" + e.getMessage());
}
return null;
}
/**
* 给指定的key赋值value,并指定过期时间
* @author liaochao
* @Date 2020.04.09
* @param key
* @return
*/
public <T> boolean setCacheValueForTimes(String key, T value,long time,TimeUnit tu){
boolean state = true;
try{
redisTemplate.opsForValue().set(key, value, time, tu);
}catch (Exception e){
e.printStackTrace();
state = false;
log.info("redis string type,set error,key:"+key+",value:"+value+",msg:"+e.getMessage());
}
return state;
}
/**
* 对指定的key进行自增1
* @author liaochao
* @Date 2020.04.09
* @param key
* @return
*/
public long testInckey(String key){
long result = 0;
try{
result = redisTemplate.boundValueOps(key).increment(1);
}catch (Exception e){
e.printStackTrace();
log.info("redis string type,set error,key:temporary,value:"+result+",msg:"+e.getMessage());
result = -1;
}
return result;
}
/**
* 对指定的key进行自减1
* @author liaochao
* @Date 2020.04.09
* @param key
* @return
*/
public long testDeckey(String key){
long result = 0;
try{
result = redisTemplate.boundValueOps(key).decrement(1);
}catch (Exception e){
e.printStackTrace();
log.info("redis string type,set error,key:temporary,value:"+result+",msg:"+e.getMessage());
result = -1;
}
return result;
}
/**
* 获取key对应的value值,传入value的类型,获取出来也是转换了类型的value值
* @author liaochao
* @Date 2020.04.09
* @param key
* @return
*/
public <T> T getValue(String key,Class<T> clazz){
try{
String s = ""+ redisTemplate.opsForValue().get(key);
T value = JSON.parseObject(s,clazz);
return value;
}catch (Exception e){
e.printStackTrace();
log.info("redis string type,get error,key:"+key+",msg:"+e.getMessage());
}
return null;
}
/**
* 删除key
* @param key
* @return
*/
public boolean delete(String key){
boolean result = false;
try{
result = redisTemplate.delete(key);
}catch (Exception e){
log.info("redis string type,set error,key:"+key+",msg:"+e.getMessage());
}
return result;
}
}
这样在其他地方使用,引入这个类就可以了。这里没有写操作集合的,读者自己完成。
二 、采用Jedis
①导包:
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.7.3</version>
</dependency>
②配置yml
spring:
redis:
host: localhost
password: redis
port: 6379
# Redis数据库索引(默认为0)
database: 0
# 连接超时时间(毫秒)
timeout: 0
jedis:
pool:
# 最大连接池数
max-active: 100
# 连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: 20
# 连接池中的最小空闲连接
min-idle: 0
# 连接池中的最大空闲连接
max-idle: 100
③写一个JedisPool配置类
@Configuration // 配置类
@EnableCaching // 开启缓存(可不写这个注解)
public class RedisConfig {
@Value("${spring.redis.host}") // 注入配置文件中的属性
private String host;
@Value("${spring.redis.port}")
private int port;
@Value("${spring.redis.password}")
private String password;
@Value("${spring.redis.timeout}")
private int timeout;
@Value("${spring.redis.jedis.pool.max-idle}")
private int maxIdle;
@Value("${spring.redis.jedis.pool.min-idle}")
private int minIdle;
@Value("${spring.redis.jedis.pool.max-active}")
private int maxActive;
@Value("${spring.redis.jedis.pool.max-wait}")
private long maxWaitMillis;
@Bean
public JedisPool getJedisPool() {
log.info("JedisPool注入成功!!");
log.info("redis地址:" + host + ":" + port);
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxIdle(maxIdle);
jedisPoolConfig.setMaxWaitMillis(maxWaitMillis * 1000);
JedisPool jedisPool = new JedisPool(jedisPoolConfig, host, port, timeout, password);
return jedisPool;
}
}
④封装redis的操作方法的类
@Service
public class RedisService {
@Autowire
private JedisPool jedisPool;
private Jedis getResource() {
return jedisPool.getResource();
}
private void returnResource(Jedis jedis) {
if (jedis != null) {
jedis.close();
}
}
// 获取
public <T> T get(KeyPrefix prefix, String key, Class<T> clazz) {
Jedis jedis = null;
try {
jedis = getResource();
String str = jedis.get(prefix.getPrefix() + key);
return JSON.parseObject(str, clazz);
} finally {
returnResource(jedis);
}
}
// 存储
public <T> boolean set(KeyPrefix prefix, String key, T value) {
if (value == null || key == null) {
return false;
}
Jedis jedis = null;
try {
jedis = getResource();
if (prefix.expireSeconds() <= 0) {
jedis.set(prefix.getPrefix() + key, JSON.toJSONString(value));
} else {
// 设置有效期
jedis.setex(prefix.getPrefix() + key, prefix.expireSeconds(), JSON.toJSONString(value));
}
log.info("存入redis,key={}", (prefix.getPrefix() + key));
return true;
} finally {
returnResource(jedis);
}
}
// 判断key是否存在
public boolean exists(KeyPrefix prefix, String key) {
if (key == null) {
return false;
}
Jedis jedis = null;
try {
jedis = getResource();
return jedis.exists(prefix.getPrefix() + key);
} finally {
returnResource(jedis);
}
}
// 数字值增加一
public Long incr(KeyPrefix prefix, String key) {
Jedis jedis = null;
try {
jedis = getResource();
return jedis.incr(prefix.getPrefix() + key);
} finally {
returnResource(jedis);
}
}
// 数字值减少一
public Long decr(KeyPrefix prefix, String key) {
Jedis jedis = null;
try {
jedis = getResource();
return jedis.decr(prefix.getPrefix() + key);
} finally {
returnResource(jedis);
}
}
// 删除
public boolean delete(KeyPrefix prefix, String key) {
Jedis jedis = null;
try {
jedis = getResource();
return jedis.del(prefix.getPrefix() + key) > 0;
} finally {
returnResource(jedis);
}
}
这样在其他地方使用时,引入这个RedisService 就可以了。
题外话:今天遇到double类型保留两位小数的方法
例如:a是一个Double类型,有很多位小数,要把它保留两位。
BigDecimal b = new BigDecimal(a);
Double s = b.setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue();
这样得到的s就是a保留两位小数的结果了!