一、JacksonConfig 全局序列化反序列化配置
1.1yml中配置
#时区
spring.jackson.time-zone=GMT+8
#日期格式
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
#默认转json的属性,这里设置为非空才转json
spring.jackson.default-property-inclusion=non_null
#设置属性命名策略,对应jackson下PropertyNamingStrategy中的常量值,SNAKE_CASE-返回的json驼峰式转下划线,json body下划线传到后端自动转驼峰式
spring.jackson.property-naming-strategy=SNAKE_CASE
#对象为空时是否报错,默认true
spring.jackson.serialization.fail-on-empty-beans=true
#返回的java.util.date转换成timestamp
spring.jackson.serialization.write-dates-as-timestamps=true
#json中含pojo不存在属性时是否失败报错,默认true
spring.jackson.deserialization.fail-on-unknown-properties=false
#是否允许出现单引号,默认false
spring.jackson.parser.allow-single-quotes=true
1.2配置文件中配置
光标定位置在builder后面,ALT + ENTER,选择 replace lambda with anonymous class可以显示 lambda为普通方法。此处定义了一下常见类型的序列化方法
@Slf4j
@Configuration
public class JacksonConfig {
@Bean
public Jackson2ObjectMapperBuilderCustomizer customizer() {
return new Jackson2ObjectMapperBuilderCustomizer() {
@Override
public void customize(Jackson2ObjectMapperBuilder builder) {
// 全局配置序列化返回 JSON 处理
JavaTimeModule javaTimeModule = new JavaTimeModule();
javaTimeModule.addSerializer(Long.class, BigNumberSerializer.INSTANCE);
javaTimeModule.addSerializer(Long.TYPE, BigNumberSerializer.INSTANCE);
javaTimeModule.addSerializer(BigInteger.class, BigNumberSerializer.INSTANCE);
javaTimeModule.addSerializer(BigDecimal.class, ToStringSerializer.instance);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(formatter));
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(formatter));
builder.modules(javaTimeModule);
builder.timeZone(TimeZone.getDefault());
log.info("初始化 jackson 配置");
}
};
}
}
ruoyi-admin/src/main/resources/application.yml 中配置jackon jackson: # 日期格式化 date-format: yyyy-MM-dd HH:mm:ss serialization: # 格式化输出 indent_output: false # 忽略无法转换的对象 fail_on_empty_beans: false deserialization: # 允许对象忽略json中不存在的属性 fail_on_unknown_properties: false
点击Jackson2ObjectMapperBuilderCustomizer, 可以查看自动配置类:JacksonAutoConfiguration
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(Jackson2ObjectMapperBuilder.class)
static class JacksonObjectMapperBuilderConfiguration {
@Bean
@Scope("prototype")
@ConditionalOnMissingBean
Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder(ApplicationContext applicationContext,
List<Jackson2ObjectMapperBuilderCustomizer> customizers) {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
builder.applicationContext(applicationContext);
customize(builder, customizers);
return builder;
}
private void customize(Jackson2ObjectMapperBuilder builder,
List<Jackson2ObjectMapperBuilderCustomizer> customizers) {
for (Jackson2ObjectMapperBuilderCustomizer customizer : customizers) {
customizer.customize(builder);
}
}
}
1.3常见jackon注解
@JsonIgnore 忽略序列化,用于属性上 @JsonInclude(JsonInclude.Include.NON_EMPTY) 不为空时候才进行序列化和反序列化 @JsonSerialize(using = DictDataJsonSerializer.class) 序列化,如下DictDataJsonSerializer 是字典序列化的处理工具/** * 字典数据json序列化工具 * * @author itino * @deprecated 建议使用通用翻译注解 */ @Deprecated @Slf4j public class DictDataJsonSerializer extends JsonSerializer<String> implements ContextualSerializer { private String dictType; @Override public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException { try { DictService dictService = SpringUtils.getBean(DictService.class); if (ObjectUtil.isNotNull(dictService)) { String label = dictService.getDictLabel(dictType, value); gen.writeString(StringUtils.isNotBlank(label) ? label : value); } else { gen.writeString(value); } } catch (BeansException e) { log.error("字典数据未查到, 采用默认处理 => {}", e.getMessage()); gen.writeString(value); } } @Override public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException { DictDataMapper anno = property.getAnnotation(DictDataMapper.class); if (Objects.nonNull(anno) && StrUtil.isNotBlank(anno.dictType())) { this.dictType = anno.dictType(); return this; } return prov.findValueSerializer(property.getType(), property); } }
@JsonProperty( value = "pass") 接受和序列化都用 pass ,而不是 password@JsonIgnore @JsonProperty( value = "pass") public String getPassword() { return password; }
@JsonFormat(pattern = "yyyy-MM-dd") 系列化格式
1.4 若依jackson工具包
com.ruoyi.common.utils.JsonUtils ,提供序列化和反序列化 一些常用方法
二、MybatisPlus
依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
ruoyi-admin/src/main/resources/application.yml 配置文件:
- 配置了Mapper 接口的扫描
- 配置Mapper对应XML的扫描
- 配置实体类domain扫描
- 配字段驼峰规则
- 以及 p6spy的日志分析
- 配置主键生成规则,以及CRUD策略
# MyBatisPlus配置
# https://baomidou.com/config/
mybatis-plus:
# 不支持多包, 如有需要可在注解配置 或 提升扫包等级
# 例如 com.**.**.mapper com.ruoyi.system.mapper
mapperPackage: com.ruoyi.**.mapper
# 对应的 XML 文件位置
mapperLocations: classpath*:mapper/**/*Mapper.xml
# 实体扫描,多个package用逗号或者分号分隔
typeAliasesPackage: com.ruoyi.**.domain
# 启动时是否检查 MyBatis XML 文件的存在,默认不检查
checkConfigLocation: false
configuration:
# 自动驼峰命名规则(camel case)映射
mapUnderscoreToCamelCase: true
# MyBatis 自动映射策略
# NONE:不启用 PARTIAL:只对非嵌套 resultMap 自动映射 FULL:对所有 resultMap 自动映射
autoMappingBehavior: PARTIAL
# MyBatis 自动映射时未知列或未知属性处理策
# NONE:不做处理 WARNING:打印相关警告 FAILING:抛出异常和详细信息
autoMappingUnknownColumnBehavior: NONE
# 更详细的日志输出 会有性能损耗 org.apache.ibatis.logging.stdout.StdOutImpl
# 关闭日志记录 (可单纯使用 p6spy 分析) org.apache.ibatis.logging.nologging.NoLoggingImpl
# 默认日志输出 org.apache.ibatis.logging.slf4j.Slf4jImpl
logImpl: org.apache.ibatis.logging.nologging.NoLoggingImpl
global-config:
# 是否打印 Logo banner
banner: true
dbConfig:
# 主键类型
# AUTO 自增 NONE 空 INPUT 用户输入 ASSIGN_ID 雪花 ASSIGN_UUID 唯一 UUID
idType: ASSIGN_ID
# 逻辑已删除值
logicDeleteValue: 2
# 逻辑未删除值
logicNotDeleteValue: 0
# 字段验证策略之 insert,在 insert 的时候的字段验证策略
# IGNORED 忽略 NOT_NULL 非NULL NOT_EMPTY 非空 DEFAULT 默认 NEVER 不加入 SQL
insertStrategy: NOT_NULL
# 字段验证策略之 update,在 update 的时候的字段验证策略
updateStrategy: NOT_NULL
# 字段验证策略之 select,在 select 的时候的字段验证策略既 wrapper 根据内部 entity 生成的 where 条件
where-strategy: NOT_NULL
com.ruoyi.framework.config.MybatisPlusConfig 配置文件,主要配置以下:自行查看
// 数据权限处理 // 分页插件 // 乐观锁插件- // 指定字段的填充策略
使用网卡信息绑定雪花生成器,防止集群雪花ID重复
1.1 常见注解
@TableName("sys_user") 标注数据库表名称@TableId(value = "user_id") 主键@Version 乐观锁(比如查询携带上 version字段,才回去更新版本)@TableLogic 删除标志(0代表存在 2代表删除):上面 yml配置的逻辑删除, 标注该注解的字段,数据库要默认设置 0
@TableField
属性 fill 指定字段的填充策略,如自动填充创建时间、更新时间等。需要实现 MyBatis-Plus 提供的
MetaObjectHandler
接口,并重写
insertFill
和updateFill
方法。若依具体实现类:com.ruoyi.framework.handler.CreateAndUpdateMetaObjectHandler
exist 标记是否为数据库表字段,默认为
true
。如果设置为false
,则表示该字段不是数据库表的字段,不会参与 SQL 语句的生成示例: @TableField(exist = false) private List<SysRole> roles;value
- 数据库字段名,用于指定实体类字段对应的数据库字段名。当实体类字段名与数据库字段名不一致时使用。
- 示例:
@TableField("db_column_name")
update
- 用于 SQL 的 SET 语句,设置字段更新的策略。通常与
@TableLogic
注解一起使用,实现逻辑删除。- 示例:
@TableField(update = "deleted=1")
nsertStrategy 和 updateStrategy
- 字段的插入和更新策略。
FieldStrategy
是一个枚举类,包含以下值:IGNORED
(忽略)、NOT_NULL
(非 NULL 则更新)、NOT_EMPTY
(非空则更新)、ALWAYS
(总是更新)。- 示例:
- @TableField( insertStrategy = FieldStrategy.NOT_EMPTY, updateStrategy = FieldStrategy.NOT_EMPTY, whereStrategy = FieldStrategy.NOT_EMPTY )
select
- 是否进行 select 查询。默认为
true
,表示该字段会参与查询。如果设置为false
,则查询时不会包含该字段。- 示例:
@TableField(select = false)
jdbcType
- 字段的 JDBC 类型。通常用于指定某些特殊类型的字段,如枚举类型。
- 示例:
@TableField(updateStrategy = FieldStrategy.IGNORED, jdbcType = JdbcType.VARCHAR)el
- 支持 EL 表达式,用于复杂字段的映射处理。
- 示例:
@TableField(el = "column + '_suffix'")
condition
- 用于 SQL WHERE 语句的条件,通常与
@Select
注解一起使用,实现动态 SQL。- 示例:
@TableField(condition = "name != null and name = #{name}")
strategy
- 字段验证策略,与
insertStrategy
和updateStrategy
功能类似,但用于全局配置。- 示例:
@TableField(strategy = FieldStrategy.NOT_EMPTY)
1.2 BaseMapperPlus
若依继承了 mybatis-plus的BaseMapper<T> 接口 ,自定义了 BaseMapperPlus<M, T, V> Mapper接口:com.ruoyi.common.core.mapper.BaseMapperPlus
- 提供泛型的转换
- 提供BaseMapper原有接口的封装
- 提供其他新增的查询方法
1.3分布式主键 雪花ID
1-yml中配置雪花: dbConfig: # 主键类型 # AUTO 自增 NONE 空 INPUT 用户输入 ASSIGN_ID 雪花 ASSIGN_UUID 唯一 UUID idType: ASSIGN_ID2-com.ruoyi.framework.config.MybatisPlusConfig 类中注入IdentifierGenerator ,具体实现自行查看
/** * 使用网卡信息绑定雪花生成器 * 防止集群雪花ID重复 */ @Bean public IdentifierGenerator idGenerator() { return new DefaultIdentifierGenerator(NetUtil.getLocalhost()); }
1.4 wapper
关于条件构造器: wapper 学习文章可以参考
mybatis-plus中wrapper的用法(详细)_mybatisplus wrapper-CSDN博客https://blog.csdn.net/qq_39715000/article/details/120090033上文未提及一些常用函数
1-apply() 函数 :将要添加到 SQL 语句中的 SQL 片段作为参数传递给它即可
//简单查询
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.apply("id = 1 or name like '%test%'");
List<User> userList = userMapper.selectList(wrapper);
//日期
apply("date_format(dateColumn,'%Y-%m-%d') = {0}", "2020-10-08")
apply("date_format(dateColumn,{0}) = {1}", "%Y-%m-%d", "2020-10-08")
2-func 函数:可以添加if 等判断
LambdaQueryWrapper<SysOperLog> lqw = new LambdaQueryWrapper<SysOperLog>()
.like(StringUtils.isNotBlank(operLog.getTitle()), SysOperLog::getTitle, operLog.getTitle())
.eq(operLog.getBusinessType() != null && operLog.getBusinessType() > 0,
SysOperLog::getBusinessType, operLog.getBusinessType())
.func(f -> {
if (ArrayUtil.isNotEmpty(operLog.getBusinessTypes())) {
f.in(SysOperLog::getBusinessType, Arrays.asList(operLog.getBusinessTypes()));
}
})
3- nested 嵌套查询: nested函数中语句会加上()作为整体提升优先级
public void complexQuery() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("status", 1)
.nested(i -> i.eq("name", "John").or().like("email", "example%"))
.orderByAsc("id");
List<User> userList = userMapper.selectList(queryWrapper);
}
SELECT * FROM user WHERE status = 1 AND (name = 'John' OR email LIKE 'example%') ORDER BY id ASC
三、BeanCopyUtils
com.ruoyi.common.utils.BeanCopyUtils 包中 ,提供:(基于 cglib 性能优异)
- Bean to Bean
- Bean to Map
- Map to Bean
- Map to Map
- List copy
四、Redis
1.1 Redisson
功能丰富:Redisson提供了Redis各种数据结构的Java实现,以及分布式锁、计数器等高级功能,满足复杂场景需求。
易于集成:友好的API和与多种Java框架的集成支持,使得开发者能够轻松地将Redis集成到Java应用中。
高性能与可扩展:基于Redis的内存存储和集群支持,Redisson实现了高读写速度和水平扩展能力,适用于高并发和大规模应用。
依赖
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-data-27</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>lock4j-redisson-spring-boot-starter</artifactId>
</dependency>
1.2 Redisson 配置文件和配置类
配置文件 yml中,com.ruoyi.framework.config.properties.RedissonProperties 是其配置类。
下面分别是单机 和集群配置类。
/** * 单机服务配置 */ private SingleServerConfig singleServerConfig; /** * 集群服务配置 */ private ClusterServersConfig clusterServersConfig;
redisson:
# redis key前缀
keyPrefix: ruoyi-vue-plus
# 线程池数量
threads: 4
# Netty线程池数量
nettyThreads: 8
# 单节点配置
singleServerConfig:
# 客户端名称
clientName: ${ruoyi.name}
# 最小空闲连接数
connectionMinimumIdleSize: 8
# 连接池大小
connectionPoolSize: 32
# 连接空闲超时,单位:毫秒
idleConnectionTimeout: 10000
# 命令等待超时,单位:毫秒
timeout: 3000
# 发布和订阅连接池大小
subscriptionConnectionPoolSize: 50
com.ruoyi.framework.config.RedisConfig 类,是redisson的配置类。
@Bean
public RedissonAutoConfigurationCustomizer redissonCustomizer() {
return config -> {
config.setThreads(redissonProperties.getThreads())
.setNettyThreads(redissonProperties.getNettyThreads())
.setCodec(new JsonJacksonCodec(objectMapper));
RedissonProperties.SingleServerConfig singleServerConfig = redissonProperties.getSingleServerConfig();
if (ObjectUtil.isNotNull(singleServerConfig)) {
// 使用单机模式
config.useSingleServer()
//设置redis key前缀
.setNameMapper(new KeyPrefixHandler(redissonProperties.getKeyPrefix()))
.setTimeout(singleServerConfig.getTimeout())
.setClientName(singleServerConfig.getClientName())
.setIdleConnectionTimeout(singleServerConfig.getIdleConnectionTimeout())
.setSubscriptionConnectionPoolSize(singleServerConfig.getSubscriptionConnectionPoolSize())
.setConnectionMinimumIdleSize(singleServerConfig.getConnectionMinimumIdleSize())
.setConnectionPoolSize(singleServerConfig.getConnectionPoolSize());
}
// 集群配置方式 参考下方注释
RedissonProperties.ClusterServersConfig clusterServersConfig = redissonProperties.getClusterServersConfig();
if (ObjectUtil.isNotNull(clusterServersConfig)) {
config.useClusterServers()
//设置redis key前缀
.setNameMapper(new KeyPrefixHandler(redissonProperties.getKeyPrefix()))
.setTimeout(clusterServersConfig.getTimeout())
.setClientName(clusterServersConfig.getClientName())
.setIdleConnectionTimeout(clusterServersConfig.getIdleConnectionTimeout())
.setSubscriptionConnectionPoolSize(clusterServersConfig.getSubscriptionConnectionPoolSize())
.setMasterConnectionMinimumIdleSize(clusterServersConfig.getMasterConnectionMinimumIdleSize())
.setMasterConnectionPoolSize(clusterServersConfig.getMasterConnectionPoolSize())
.setSlaveConnectionMinimumIdleSize(clusterServersConfig.getSlaveConnectionMinimumIdleSize())
.setSlaveConnectionPoolSize(clusterServersConfig.getSlaveConnectionPoolSize())
.setReadMode(clusterServersConfig.getReadMode())
.setSubscriptionMode(clusterServersConfig.getSubscriptionMode());
}
log.info("初始化 redis 配置");
};
}
1.3 redis 和redisson集群配置文件
/**
* redis集群配置 yml
*
* --- # redis 集群配置(单机与集群只能开启一个另一个需要注释掉)
* spring:
* redis:
* cluster:
* nodes:
* - 192.168.0.100:6379
* - 192.168.0.101:6379
* - 192.168.0.102:6379
* # 密码
* password:
* # 连接超时时间
* timeout: 10s
* # 是否开启ssl
* ssl: false
*
* redisson:
* # 线程池数量
* threads: 16
* # Netty线程池数量
* nettyThreads: 32
* # 集群配置
* clusterServersConfig:
* # 客户端名称
* clientName: ${ruoyi.name}
* # master最小空闲连接数
* masterConnectionMinimumIdleSize: 32
* # master连接池大小
* masterConnectionPoolSize: 64
* # slave最小空闲连接数
* slaveConnectionMinimumIdleSize: 32
* # slave连接池大小
* slaveConnectionPoolSize: 64
* # 连接空闲超时,单位:毫秒
* idleConnectionTimeout: 10000
* # 命令等待超时,单位:毫秒
* timeout: 3000
* # 发布和订阅连接池大小
* subscriptionConnectionPoolSize: 50
* # 读取模式
* readMode: "SLAVE"
* # 订阅模式
* subscriptionMode: "MASTER"
*/
1.4 RedisUtils 工具类
所在包 :com.ruoyi.common.utils.redis.RedisUtils
1、 订阅发布测试类以及结果如下;
@Test
void subPub(){
String key = "key";
//模拟订阅消息 启动后会一直监听消息
RedisUtils.subscribe(key, String.class, consumer -> {
Console.log("key:{}", key);
Console.log("consumer:{}", consumer);
});
//模拟发布
RedisUtils.publish(key,"发布一则消息1!");
RedisUtils.publish(key,"发布一则消息2!");
RedisUtils.publish(key,"ok", conumer->{
Console.log("consumer3:{}", conumer);
});
}
key:key
consumer:发布一则消息1!
key:key
consumer:发布一则消息2!
consumer3:ok
key:key
consumer:ok
2、设置缓存
@Test
void setCacheObject(){
//ttl = -1 ,永久有效印版不用
RedisUtils.setCacheObject("java", "helloWord");
//ttl 自定义, 60秒有效期
RedisUtils.setCacheObject("java", "helloWord", Duration.ofSeconds(60));
//是否保留TTL有效期(例如: set之前ttl剩余60 set之后还是为60),false 表示永久
RedisUtils.setCacheObject("java", "helloWord", true);
//果不存在则设置 并返回 true 如果存在则返回 false
boolean ifAbsent = RedisUtils.setObjectIfAbsent("java", "helloWord", Duration.ofSeconds(60));
}
3、设置监听
redis中配置 ,key 监听器配置 : notify-keyspace-event ,如下:(接口中红线标注要包含的 字母,其他接口自行查看)
# Redis服务器配置
# 绑定IP地址
#解除本地限制 注释bind 127.0.0.1
#bind 127.0.0.1
# 服务器端口号
port 6379
#配置密码,不要可以删掉
#requirepass
#key 监听器配置
notify-keyspace-events Exg
# 服务器运行模式,Redis以守护进程方式运行,默认为no,改为yes意为以守护进程方式启动,可后台运行,除非kill进程,改为yes会使配置文件方式启动redis失败,如果后面redis启动失败,就将这个注释掉
daemonize no
#当Redis以守护进程方式运行时,Redis默认会把pid写入/var/run/redis.pid文件,可以通过pidfile指定(自定义)
#pidfile /data/dockerData/redis/run/redis6379.pid
#默认为no,redis持久化,可以改为yes
appendonly yes
监听测试类:
package com.ruoyi.demo.listener;
import cn.hutool.core.lang.Console;
import com.ruoyi.common.utils.redis.RedisUtils;
import org.redisson.api.DeletedObjectListener;
import org.redisson.api.ExpiredObjectListener;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
/**
* <简述>
* <详细描述>
*
* @author syf
* @date 2024年03月18日 22:38
*/
@Component
public class ExpiredListener {
@PostConstruct
public void expireListener(){
Console.log("启动监听器。。。。");
//用于监听 Redisson 分布式缓存中对象的过期事件
RedisUtils.addObjectListener("java", new ExpiredObjectListener() {
@Override
public void onExpired(String name) {
Console.log("ExpiredObjectListener:{}", name);
}
});
//监听删除
RedisUtils.addObjectListener("java", new DeletedObjectListener() {
@Override
public void onDeleted(String name) {
Console.log("DeletedObjectListener:{}", name);
}
});
}
}
结果:监听到删除
4-对象操作
常用操作
@Test
void getObject(){
RedisUtils.setCacheObject("java", "helloWord");
//6-校验对象是否存在
RedisUtils.isExistsObject("java");
//1-设置过期时间
RedisUtils.expire("java", Duration.ofSeconds(10));
//2-获取对象
Object name = RedisUtils.getCacheObject("name");
Console.log("name:{}", name);
//3-获取剩余存活时间
long time = RedisUtils.getTimeToLive("name");
Console.log("time:{}", time);
//4-删除
RedisUtils.deleteObject("name");
//5-删除集合
List<String> list = new ArrayList<>();
list.add("java1");
list.add("java2");
RedisUtils.setCacheObject("java1", "helloWord1");
RedisUtils.setCacheObject("java2", "helloWord2");
RedisUtils.deleteObject(list);
}
5-数组操作
数组操作是拼接,不会覆盖,对象操作则是覆盖,注意使用场景
提供集合的操作下:
@Test
void saveList(){
//这个实际保存是对象 (覆盖之前 list1)
List<String> list = Arrays.asList("java1", "java2");
RedisUtils.setCacheObject("list1", list, Duration.ofSeconds(60));
//保存是数组 (不会覆盖之前的数据 list2)
RedisUtils.setCacheList("list2", list);
//取
List<String> list2 = RedisUtils.getCacheList("list2");
//set集合 值不重复
Set<String> set = new HashSet<>();
set.add("java1");
set.add("java2");
RedisUtils.setCacheSet("set", set);
RedisUtils.getCacheSet("set");
//Map
Map<String, Object> map = new HashMap<>();
map.put("java1", "String");
map.put("java2", "Integer");
//存
RedisUtils.setCacheMap("map", map);
//取
Object value = RedisUtils.getCacheMapValue("map", "java1");
//修改map 里面值
RedisUtils.setCacheMapValue("java1", "map", "null");
//取map 里面值(自定义map 用得少)
Set<String> objects = new HashSet<>();
objects.add("java1");
objects.add("java2");
Map<String, Object> map2 = RedisUtils.getMultiCacheMapValue("map", objects);
//取
Map<String, Object> cacheMap = RedisUtils.getCacheMap("map");
//遍历key
Set<String> map1 = RedisUtils.getCacheMapKeySet("map");
}
6-原子操作
原子操作,创建后,利用 增加 减少方法去修改
@Test
void steAtom(){
//原子操作
RedisUtils.setAtomicValue("count" ,1);
//增加
RedisUtils.incrAtomicValue("count");
//减少
RedisUtils.decrAtomicValue("count");
//获取
long atomicValue = RedisUtils.getAtomicValue(":count");
}
7-根据前缀获取
@Test
void getKeys() {
//get
String prefix = "ruoyi-vue-plus:sys";
Collection<String> keys = RedisUtils.keys(prefix + "*");
List<String> list = new ArrayList<>(keys);
for (String s : list) {
Console.log("value:{}", s);
}
//删除
String prefix1 = "list1";
RedisUtils.deleteKeys(prefix1 + "*");
}
结果:
value:sys_config
value:sys_oss_config
value:sys_oss:default_config
value:sys_dict
8-是否存在
@Test
void getExists() {
//是否存在
boolean hasKey = RedisUtils.hasKey("list2");
boolean existsObjectis = RedisUtils.isExistsObject("list2");
}