技术标签: spring boot java redis
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
spring:
## Redis 配置
redis:
## Redis数据库索引(默认为0)
database: 0
## Redis服务器地址
host: localhost
## Redis服务器连接端口
port: 6379
## Redis服务器连接密码(默认为空)
password: root
jedis:
pool:
## 连接池最大连接数(使用负值表示没有限制)
#spring.redis.pool.max-active=8
max-active: 8
## 连接池最大阻塞等待时间(使用负值表示没有限制)
#spring.redis.pool.max-wait=-1
max-wait: -1
## 连接池中的最大空闲连接
#spring.redis.pool.max-idle=8
max-idle: 8
## 连接池中的最小空闲连接
#spring.redis.pool.min-idle=0
min-idle: 0
## 连接超时时间(毫秒)
timeout: 1200
SpringBoot自动帮我们在容器中生成了一个RedisTemplate和一个StringRedisTemplate。但是,这个RedisTemplate的泛型是<Object,Object>,写代码不方便,需要写好多类型转换的代码;我们需要一个泛型为<String,Object>形式的RedisTemplate。并且,这个RedisTemplate没有设置数据存在Redis时,key及value的序列化方式。
重新配置一个RedisTemplate
package org.example.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.*;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
// 配置连接工厂
template.setConnectionFactory(factory);
//序列化和反序列化redis中的值
Jackson2JsonRedisSerializer jackson = new Jackson2JsonRedisSerializer(Object.class);
//Java对象转换成JSON结构
ObjectMapper objectMapper = new ObjectMapper();
// 指定要序列化的域
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
// 指定序列化输入的类型
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson.setObjectMapper(objectMapper);
// 值采用json序列化
template.setValueSerializer(jackson);
//使用StringRedisSerializer来序列化和反序列化redis的key值
template.setKeySerializer(new StringRedisSerializer());
// 设置hash key和value序列化模式
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(jackson);
template.afterPropertiesSet();
return template;
}
}
直接用RedisTemplate操作Redis,需要很多行代码,因此直接封装好一个RedisUtils,这样写代码更方便点。这个RedisUtils交给Spring容器实例化,使用时直接注解注入。
工具类代码如下:
package org.example.Util;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
@Component
public class RedisUtil {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
//===============缓存相关方法===============
//指定缓存失效时间
public boolean expire(String key, long time) {
try {
if (time > 0) {
redisTemplate.expire(key, time, TimeUnit.SECONDS);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
//根据key获取过期时间,返回0代表为永久有效
public long getExpire(String key) {
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
}
//===============数据类型为String的相关方法===============
//根据key值获取缓存值
public Object stringGet(String key) {
return key == null ? null : redisTemplate.opsForValue().get(key);
}
//根据key值存入数据类型为String的缓存值
public boolean stringSet(String key, Object value) {
try {
redisTemplate.opsForValue().set(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
//根据key值存入数据类型为String的缓存值并设置时间
public boolean stringSetWithTime(String key, Object value, long time) {
try {
if (time > 0) {
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
} else {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
//删除缓存
public void stringDelete(String... key) {
if (key != null && key.length > 0) {
if (key.length == 1) {
redisTemplate.delete(key[0]);
} else {
redisTemplate.delete((Collection<String>) CollectionUtils.arrayToList(key));
}
}
}
//===============数据类型为Hash的相关方法===============
//根据key和item获取缓存值
public Object hashGet(String key, String item) {
return redisTemplate.opsForHash().get(key, item);
}
//根据key和item存入数据类型为Hash的缓存值
public boolean hashSet(String key, String item, Object value) {
try {
redisTemplate.opsForHash().put(key, item, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
//根据key和item存入数据类型为Hash的缓存值并设置时间
public boolean hashSetWithTime(String key, String item, Object value, long time) {
try {
redisTemplate.opsForHash().put(key, item, value);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
//删除缓存
public void hashDelete(String key, Object... item) {
redisTemplate.opsForHash().delete(key, item);
}
//===============数据类型为SET的相关方法===============
//根据key值获取缓存值
public Set<Object> setGet(String key) {
try {
return redisTemplate.opsForSet().members(key);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
//根据key值存入数据类型为SET的缓存值
public long setSet(String key, Object... values) {
try {
return redisTemplate.opsForSet().add(key, values);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
//根据key值存入数据类型为SET的缓存值并设置时间
public long setSetWithTime(String key, long time, Object... values) {
try {
Long count = redisTemplate.opsForSet().add(key, values);
if (time > 0) {
expire(key, time);
}
return count;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
//删除缓存
public long setDelete(String key, Object... values) {
try {
Long count = redisTemplate.opsForSet().remove(key, values);
return count;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
//===============数据类型为LIST的相关方法===============
//获取List缓存的内容,从start到end,若从0到-1代表所有值
public List<Object> listGet(String key, long start, long end) {
try {
return redisTemplate.opsForList().range(key, start, end);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
//根据key值存入数据类型为List的缓存值
public boolean listSet(String key, Object value) {
try {
redisTemplate.opsForList().rightPush(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
//根据key值存入数据类型为List的缓存值并设置时间
public boolean listSetWithTime(String key, Object value, long time) {
try {
redisTemplate.opsForList().rightPush(key, value);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
//删除缓存
public long listDelete(String key, long count, Object value) {
try {
Long remove = redisTemplate.opsForList().remove(key, count, value);
return remove;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
}
文章浏览阅读405次。没有第三方控件用RadioGroup做轮播图--MainActivity 主页面和布局_mainactivity类怎么转成radiogroup类
文章浏览阅读1.9w次,点赞9次,收藏22次。本文原文出处: http://blog.csdn.net/bluishglc/article/details/50945032 严禁任何形式的转载,否则将委托CSDN官方维护权益!在Spark的官方文档再三强调那些将要作用到RDD上的操作,都会被分发到各个worker节点上去执行,我们都知道,这些操作实际上就是一些函数和涉及的变量组成的闭包,这里显然涉及到一个容易被忽视的问题:闭包的“序列化”。显然_闭包序列化
文章浏览阅读123次。Job dependencies Unity根据系统读取和写入的ECS组件来分析每个系统的数据依赖性。如果一个在框架中较早更新的系统读取了后来的系统所写的数据,或者写了后来的系统所读的数据,那么第二个系统就会依赖第一个系统。为了防止竞争条件,作业调度器在运行一个系统的作业之前,要确保该系统所依赖的所有作业已经完成。 一个系统的Dependency属性是一个JobHandle,代表了该系统的ECS相关依赖关系。在OnUpdate()之前,Dependency属性反映了系统对先前作业的传入依赖关系。默认_unity ecs1.0
文章浏览阅读1.1k次。原文链接:点击打开链接摘要: 流行技术大狂欢,5月29日即将召开的第二届研发效能嘉年华,带来了前沿技术理念及实践技术成果分享。本次峰会将有10位技术大咖进行干货分享,多角度,不同领域的带领大家了解高效研发。项目管理的主流模式有哪几种?传统项目管理通常采用的是瀑布式、部分迭代开发模式,要求在项目建设时,需求足够明确、文档足够规范,迭代过程中需求变更越多、越晚,对项目影响越大,会影响到项目的交付质量。..._项目管理干货 site:csdn.net
文章浏览阅读211次。一、常用命令列举 命令 类 说明 import ImportTool 将数据导入到集群 export ExportTool 将集群数据导出 codegen CodeGenTool ..._大数据 公参
文章浏览阅读1.9k次,点赞2次,收藏10次。MAC地址是网络设备中不变的物理地址,基于MAC地址的接入控制成了最直接,甚至可能是大多数情况下最有效的控制手段。在二层交换网络中,是通过依靠保存在交换机中的MAC地址表来进行寻址的,这时如果控制交换机中存储的MAC地址表就可以控制一些非法设备的接入,让其他设备不能与他进行通信。在华为S系列交换机中,为了实现这个目的提供了多种基于MAC地址的安全手段,如限制接口学习MAC地址表项的数量,限制交..._如何防范mac地址泛滥
文章浏览阅读1.1w次。具体来说cookie机制采用的是在客户端保持状态的方案。它是在用户端的会话状态的存贮机制,他需要用户打开客户端的cookie支持。cookie的作用就是为了解决HTTP协议无状态的缺陷所作的努力.而session机制采用的是一种在客户端与服务器之间保持状态的解决方案。同时我们也看到,由于采用服务器端保持状态的方案在客户端也需要保存一个标识,所以session机制可能需要借助于cookie机制来达到
文章浏览阅读2k次。微信小程序似乎比较火,很多公司除了自家app外都要给自家再弄个小程序,于是乎空余时间就试了试小程序,现记录下地图页面的开发。小程序官方文档也比较全,基本上面的东西都有,有前端开发经验的上手更简单。先上图 : 1.层级结构: 小程序类似于app,以页面为单位,每个页面包含4个文件: .js .json .wxml .wxss 为后缀的文件,官方文_微信公小程序地图开发
文章浏览阅读10w+次,点赞1.4k次,收藏7.9k次。Anacond的介绍Anaconda指的是一个开源的Python发行版本,其包含了conda、Python等180多个科学包及其依赖项。因为包含了大量的科学包,Anaconda的下载文件比较大(约531 MB),如果只需要某些包,或者需要节省带宽或存储空间,也可以使用Miniconda这个较小的发行版(仅包含conda和Python)。Conda是一个开源的包、环境管理器,可以用于..._anaconda
文章浏览阅读1.5k次。JDK的代理,实际上是对Java接口(Interface)的代理,而且只能对接口进行代理,达到的效果是,当调用指定接口的指定方法时,会执行特定的操作。例如,HelloService是一个接口,public String sayHello(String msg)是该接口的其中一个方法,当代码调用该接口的sayHello方法时,会执行规定好的动作。这里会有一个问题,HelloService接口的实现类是从哪里来的呢?这里HelloService接口的实现类是由代理动态生成的实现类。所以想为一个接口生成代理,需要_jdk动态代理demo
文章浏览阅读2.2k次。在UML类图中,聚合是空心菱形,组合是实心菱形。简单来说:组合的关系就像一个学生和他的各个器官,手、脚、鼻子、眼睛等器官组合成了一个学生,这些器官离开了学生这个个体,也就失去了意义,无法单独生存,因此,组合关系的类具有相同的生命周期,它们的联系更加紧密。而聚合就像一个班级有许多学生构成,学生离开了班级,作为一个个体仍然能够存活。聚合案例public ClassRoom{ public..._聚合是菱形空心吗
文章浏览阅读499次。小编经历过这么多年的摸爬滚打,面试过也被面试过。现总结与归纳Android开发相关面试题:初级面试题:1、Activity启动模式有哪些,分别有什么不同?2、Service启动模式有哪些,对应的生命周期?IntentService呢?3、ContentProvider的作用,是否支持多线程和多进程4、Broadcast的注册方式,对应的生命周期是什么,有序和无序那种可以中断广播?5、AsyncTask的作用,如何使用(包括有哪些方法,能说出同步异步,能说出不同Android版本下的区别加分)6_2022 最全android面试题合集