Java连接Redis和SpringBoot整合Redis

1. Java连接Redis

思考:我们之前操作redis都是通过命令行的客户端来操作。在开发时都是通过java项目操作redis

java提高连接redis的方式为jedis。我们需要遵循jedis协议。
java提供连接mysql的方式为jdbc。


1.1 单机模式

引入依赖

<!--引入java连接redis的驱动--><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>4.3.1</version></dependency>

若使用3.8.1的依赖,jedis中的setex方法会被划去

<dependency><groupId>repMaven.redis.clients</groupId><artifactId>jedis</artifactId><version>3.8.0</version>
</dependency>

编写代码

package com.zmq;import redis.clients.jedis.Jedis;import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;/*** @program: redis1* @description: java连接redis* @author: zmq**/
public class Test01 {public static void main(String[] args) {//连接redis的信息,默认连接本地的redis端口 端口号6379,所有关于redis操作的功能都在Jedis类中Jedis jedis=new Jedis("172.16.7.112",6379);//关于key的命令//获取所有key值Set<String> keys = jedis.keys("*");System.out.println("获取所有的keys:"+keys);//删除key的个数Long del = jedis.del("ll", "l1");System.out.println("删除key的个数"+del);//判定指定的key是否存在Boolean k4 = jedis.exists("k4");System.out.println("判断指定的k4是否存在"+k4);//给key指定过期时间jedis.expire("lll",100);//string类型//添加数据String set = jedis.set("k1", "v1");System.out.println("存入k1的值"+set);//获取指定的值String s = jedis.get("k1");System.out.println("获取指定k1的值"+s);//判断指定的值是否存在,若不存在,就创建Long k2 = jedis.setnx("k2", "v2");System.out.println("如果k2不存在,则设置k2的值:"+k2);jedis.setnx("k3","110");//值递增Long k3 = jedis.incr("k3");System.out.println("k3的值加1"+k3);//值递减Long k31 = jedis.decr("k3");System.out.println("k3的值减1"+k31);//创建key并指定过期时间String setex = jedis.setex("k4", 100, "v3");System.out.println(setex);//关于hash的命令//存值long hset = jedis.hset("h1", "name", "lay");System.out.println("存入h1的键值对:"+hset);//设置一个mapMap<String,String> map=new HashMap<>();map.put("name","章三");map.put("age","18");long h2 = jedis.hset("h2", map);System.out.println("存入h2的键值对"+h2);//取值String hget = jedis.hget("h2", "name");System.out.println("获取h2中name的值"+hget);//获取key中的素有键值对的值Map<String, String> h21 = jedis.hgetAll("h2");System.out.println("获取h2中所有键值对的值"+h21);//获取所有哈希表中的值List<String> h22 = jedis.hvals("h2");System.out.println(h22);//获取所有哈希表中所有的字段Set<String> h23 = jedis.hkeys("h2");System.out.println(h23);}
}
  • 关于连接redis的信息
  1. 连接redis的信息,默认连接本地的redis端口 端口号6379

所有关于redis操作的功能都在Jedis类中

Jedis jedis=new Jedis("172.16.8.110",6379);
  • 关于key的命令
  1. 获取所有key值——keys~~~~keys
 //获取所有key值Set<String> keys = jedis.keys("*");System.out.println("获取所有的keys:"+keys);
  1. 删除key的个数——del~~~~del
 //删除key的个数Long del = jedis.del("ll", "l1");System.out.println("删除key的个数"+del);
  1. 判定指定的可以是否存在——exists~~~~exists
   //判定指定的key是否存在Boolean k4 = jedis.exists("k4");System.out.println("判断指定的k4是否存在"+k4);
  1. 创建key并给key指定过期时间——expire~~~~expire
        //给key指定过期时间jedis.expire("lll",100);
  • 关于字符串String的命令
  1. 添加数据——set~~~~set
//添加数据String set = jedis.set("k1", "v1");System.out.println("存入k1的值"+set);
  1. 获取指定的值——get~~~~get
//获取指定的值String s = jedis.get("k1");System.out.println("获取指定k1的值"+s);
  1. 判断指定的值是否存在,若不存在,就创建——setnx~~~~setnx
        //判断指定的值是否存在,若不存在,就创建Long k2 = jedis.setnx("k2", "v2");System.out.println("如果k2不存在,则设置k2的值:"+k2);
  1. 值递增,每次加1——incr~~~~incr
        jedis.setnx("k3","110");//值递增Long k3 = jedis.incr("k3");System.out.println("k3的值加1"+k3);
  1. 值递减,每次减1——decr~~~~decr
        //值递减Long k31 = jedis.decr("k3");System.out.println("k3的值减1"+k31);
  1. 创建key并指定过期时间——setex~~~~setex
        //创建key并指定过期时间String setex = jedis.setex("k4", 100, "v3");System.out.println(setex);
  • 关于hash的命令
  1. 存值1——hset~~~~hset
//存值long hset = jedis.hset("h1", "name", "lay");System.out.println("存入h1的键值对:"+hset);
  1. 存值2,存入map——hset~~~~hset
        //设置一个mapMap<String,String> map=new HashMap<>();map.put("name","章三");map.put("age","18");long h2 = jedis.hset("h2", map);System.out.println("存入h2的键值对"+h2);
  1. 存值2,存入map

  2. 获取指定的key中指定的键值对的value值——hget~~~~hget

        //取值String hget = jedis.hget("h2", "name");System.out.println("获取h2中name的值"+hget);
  1. 获取key中所有键值对的值——hgetAll~~~~hgetAll
        //获取key中的素有键值对的值Map<String, String> h21 = jedis.hgetAll("h2");System.out.println("获取h2中所有键值对的值"+h21);
  1. 获取哈希表中所有的值——hvals~~~~hvals
        //获取所有哈希表中的值List<String> h22 = jedis.hvals("h2");System.out.println(h22);
  1. 获取哈希表中所有的字段——hkeys~~~~hkeys
        //获取所有哈希表中所有的字段Set<String> h23 = jedis.hkeys("h2");System.out.println(h23);

1.2 集群模式

  • 连接redis的信息
 public static void main(String[] args) {Set<HostAndPort> nodes=new HashSet<>();nodes.add(new HostAndPort("# 1. Java连接Redis> 思考:我们之前操作redis都是通过命令行的客户端来操作。在开发时都是通过java项目操作redisjava提高连接redis的方式jedis。我们需要遵循jedis协议。****## 1.1 单机模式**引入依赖**```xml
<!--引入java连接redis的驱动--><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>4.3.1</version></dependency>

若使用3.8.1的依赖,jedis中的setex方法会被划去

<dependency><groupId>repMaven.redis.clients</groupId><artifactId>jedis</artifactId><version>3.8.0</version>
</dependency>

编写代码

package com.zmq;import redis.clients.jedis.Jedis;import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;/*** @program: redis1* @description: java连接redis* @author: zmq**/
public class Test01 {public static void main(String[] args) {//连接redis的信息,默认连接本地的redis端口 端口号6379,所有关于redis操作的功能都在Jedis类中Jedis jedis=new Jedis("172.16.7.112",6379);//关于key的命令//获取所有key值Set<String> keys = jedis.keys("*");System.out.println("获取所有的keys:"+keys);//删除key的个数Long del = jedis.del("ll", "l1");System.out.println("删除key的个数"+del);//判定指定的key是否存在Boolean k4 = jedis.exists("k4");System.out.println("判断指定的k4是否存在"+k4);//给key指定过期时间jedis.expire("lll",100);//string类型//添加数据String set = jedis.set("k1", "v1");System.out.println("存入k1的值"+set);//获取指定的值String s = jedis.get("k1");System.out.println("获取指定k1的值"+s);//判断指定的值是否存在,若不存在,就创建Long k2 = jedis.setnx("k2", "v2");System.out.println("如果k2不存在,则设置k2的值:"+k2);jedis.setnx("k3","110");//值递增Long k3 = jedis.incr("k3");System.out.println("k3的值加1"+k3);//值递减Long k31 = jedis.decr("k3");System.out.println("k3的值减1"+k31);//创建key并指定过期时间String setex = jedis.setex("k4", 100, "v3");System.out.println(setex);//关于hash的命令//存值long hset = jedis.hset("h1", "name", "lay");System.out.println("存入h1的键值对:"+hset);//设置一个mapMap<String,String> map=new HashMap<>();map.put("name","章三");map.put("age","18");long h2 = jedis.hset("h2", map);System.out.println("存入h2的键值对"+h2);//取值String hget = jedis.hget("h2", "name");System.out.println("获取h2中name的值"+hget);//获取key中的素有键值对的值Map<String, String> h21 = jedis.hgetAll("h2");System.out.println("获取h2中所有键值对的值"+h21);//获取所有哈希表中的值List<String> h22 = jedis.hvals("h2");System.out.println(h22);//获取所有哈希表中所有的字段Set<String> h23 = jedis.hkeys("h2");System.out.println(h23);}
}
  • 关于连接redis的信息
  1. 连接redis的信息,默认连接本地的redis端口 端口号6379

所有关于redis操作的功能都在Jedis类中

Jedis jedis=new Jedis("172.16.8.110",6379);
  • 关于key的命令
  1. 获取所有key值——keys~~~~keys
 //获取所有key值Set<String> keys = jedis.keys("*");System.out.println("获取所有的keys:"+keys);
  1. 删除key的个数——del~~~~del
 //删除key的个数Long del = jedis.del("ll", "l1");System.out.println("删除key的个数"+del);
  1. 判定指定的可以是否存在——exists~~~~exists
   //判定指定的key是否存在Boolean k4 = jedis.exists("k4");System.out.println("判断指定的k4是否存在"+k4);
  1. 创建key并给key指定过期时间——expire~~~~expire
        //给key指定过期时间jedis.expire("lll",100);
  • 关于字符串String的命令
  1. 添加数据——set~~~~set
//添加数据String set = jedis.set("k1", "v1");System.out.println("存入k1的值"+set);
  1. 获取指定的值——get~~~~get
//获取指定的值String s = jedis.get("k1");System.out.println("获取指定k1的值"+s);
  1. 判断指定的值是否存在,若不存在,就创建——setnx~~~~setnx
        //判断指定的值是否存在,若不存在,就创建Long k2 = jedis.setnx("k2", "v2");System.out.println("如果k2不存在,则设置k2的值:"+k2);
  1. 值递增,每次加1——incr~~~~incr
        jedis.setnx("k3","110");//值递增Long k3 = jedis.incr("k3");System.out.println("k3的值加1"+k3);
  1. 值递减,每次减1——decr~~~~decr
        //值递减Long k31 = jedis.decr("k3");System.out.println("k3的值减1"+k31);
  1. 创建key并指定过期时间——setex~~~~setex
        //创建key并指定过期时间String setex = jedis.setex("k4", 100, "v3");System.out.println(setex);
  • 关于hash的命令
  1. 存值1——hset~~~~hset
//存值long hset = jedis.hset("h1", "name", "lay");System.out.println("存入h1的键值对:"+hset);
  1. 存值2,存入map——hset~~~~hset
        //设置一个mapMap<String,String> map=new HashMap<>();map.put("name","章三");map.put("age","18");long h2 = jedis.hset("h2", map);System.out.println("存入h2的键值对"+h2);
  1. 存值2,存入map

  2. 获取指定的key中指定的键值对的value值——hget~~~~hget

        //取值String hget = jedis.hget("h2", "name");System.out.println("获取h2中name的值"+hget);
  1. 获取key中所有键值对的值——hgetAll~~~~hgetAll
        //获取key中的素有键值对的值Map<String, String> h21 = jedis.hgetAll("h2");System.out.println("获取h2中所有键值对的值"+h21);
  1. 获取哈希表中所有的值——hvals~~~~hvals
        //获取所有哈希表中的值List<String> h22 = jedis.hvals("h2");System.out.println(h22);
  1. 获取哈希表中所有的字段——hkeys~~~~hkeys
        //获取所有哈希表中所有的字段Set<String> h23 = jedis.hkeys("h2");System.out.println(h23);

1.2 集群模式

  • 连接redis的信息
 public static void main(String[] args) {Set<HostAndPort> nodes=new HashSet<>();nodes.add(new HostAndPort("192.168.112.189",7001));nodes.add(new HostAndPort("192.168.112.189",7002));nodes.add(new HostAndPort("192.168.112.189",7003));nodes.add(new HostAndPort("192.168.112.189",7004));nodes.add(new HostAndPort("192.168.112.189",7005));nodes.add(new HostAndPort("192.168.112.189",7006));JedisCluster jedisCluster=new JedisCluster(nodes);jedisCluster.set("k5","666");System.out.println(jedisCluster.get("k5"));}

适合ssm项目

2. springboot整合redis

starter启动依赖——包含自动装配类,完成相应的装配功能

在这里插入图片描述

  • 有关依赖——spring-boot-starter-data-redis
<!--引入了redis整合springboot 的依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>
  • 修改配置文件
#单机模式的配置
#Redis服务器连接端口
spring.redis.port=6379
#Redis服务器地址
spring.redis.host=IP地址
#Redis数据库索引(默认为0)
spring.redis.database=1
#连接池最大连接数(使用负值表示没有限制)
#spring.redis.jedis.pool.max-active=100
#连接池中的最大空闲连接
spring.redis.jedis.pool.max-idle=10
#连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.jedis.pool.max-wait=10000ms
  • 使用

springboot整合redis时封装了两个工具类:StringRedisTemplate和RedisTemplate——springboot中用于操作redsi的类

StringRedisTemplate它是RedisTemplate的子类。StringRedisTemplate里面只能存放字符串的内容

2.1 StringRedisTemplate

在测试类中进行相关方法的测试

首先需要自动注入StringRedisTemplate类

StringRedisTemplate类:是RedisTemplate的子类,key和value均为字符串

在这里插入图片描述

RedisTemplate中定义了5中数据结构操作

stringRedisTemplate.opsForValue();//操作字符串stringRedisTemplate.opsForHash();//操作hashstringRedisTemplate.opsForList();//操作列表stringRedisTemplate.opsForSet();//操作无序集合stringRedisTemplate.opsForZSet();//操作有序集合——有序是score的有序
  • 关于key的操作
  1. 获取所有的key——keys
//获取所有的keySet<String> keys = stringRedisTemplate.keys("*");System.out.println("所有的key:"+keys);

返回值为Set集合,因为key唯一

  1. 是否删除指定的key,返回值为boolean——delete——释放锁
        //删除指定的key——返回值为booleanBoolean k1 = stringRedisTemplate.delete("k1");System.out.println("是否删除指定的k1:"+k1);

返回值为boolean

  1. 是否存在指定key——haskey
        //判断指定的key是否存在——返回值为booleanBoolean k11 = stringRedisTemplate.hasKey("k1");System.out.println("是否存在k1:"+k11);

返回值为boolean

  1. 是否设置过期时间——expire
        //设置过期时间——返回值为booleanBoolean k12 = stringRedisTemplate.expire("k1", 10, TimeUnit.HOURS);System.out.println("是否设置过期时间:"+k12);

返回值为boolean

  1. 根据key获取过期时间——getExpire
//根据key获取过期时间  stringRedisTemplate.getExpire("test");
  1. 根据key获取过期时间并换算成指定的单位——getExpire
//根据key获取过期时间并换算成指定单位 stringRedisTemplate.getExpire("test",TimeUnit.SECONDS); 

getExpire(“test”,TimeUnit.SECONDS)

//关于key的操作@Testvoid testKeys() {//获取所有的keySet<String> keys = stringRedisTemplate.keys("*");System.out.println("所有的key:"+keys);//删除指定的key——返回值为booleanBoolean k1 = stringRedisTemplate.delete("k1");System.out.println("是否删除指定的k1:"+k1);//判断指定的key是否存在——返回值为booleanBoolean k11 = stringRedisTemplate.hasKey("k1");System.out.println("是否存在k1:"+k11);//设置过期时间——返回值为booleanBoolean k12 = stringRedisTemplate.expire("k1", 10, TimeUnit.HOURS);System.out.println("是否设置过期时间:"+k12);}
  • 关于String的操作
  1. 得到操作字符串的类对象——opsForValue
//得到操作字符串的类对象ValueOperations<String, String> opsForValue = stringRedisTemplate.opsForValue();
  1. 存放数据——set
        //存放数据---set(k,v)opsForValue.set("k1","v1");
  1. 存放数据,含有过期时间——set
 //存放数据--setex(k,second,v)opsForValue.set("k2","20",2,TimeUnit.MINUTES); 
  1. 存放数据,先判断是否已存在——setIfAbsent——分布式锁
//存放数据--setnx(k,v)Boolean aBoolean = opsForValue.setIfAbsent("k3", "v3", 2, TimeUnit.MINUTES);System.out.println("是否设置成功:"+aBoolean);  
  1. 根据key获取val——get
//获取指定的元素String k1 = opsForValue.get("k1");System.out.println("获取指定的元素:"+k1);
  1. 自增——incream
//自增Long k21 = opsForValue.increment("k2");System.out.println("自增1:"+k21);
  1. 自增指定长度——incream
        //自增指定长度Long k2 = opsForValue.increment("k2", 10);System.out.println("获取指定的元素:"+k2);
  1. 自减指定长度——incream,数值为负数即可
        //自减Long k22 = opsForValue.increment("k2", -1);System.out.println("获取指定的元素:"+k22);
  1. 重新赋值——getAndSet
        //重新赋值String andSet = opsForValue.getAndSet("k1", "vvvv");System.out.println("重新赋值:"+andSet);
 //关于String的操作: 在封装的StringRedisTemplate类对应每种数据类型的操作 对应相应的类来完成@Testvoid testString() {//得到操作字符串的类对象ValueOperations<String, String> opsForValue = stringRedisTemplate.opsForValue();//存放数据---set(k,v)opsForValue.set("k1","v1");//存放数据--setex(k,second,v)opsForValue.set("k2","20",2,TimeUnit.MINUTES);//存放数据--setnx(k,v)Boolean aBoolean = opsForValue.setIfAbsent("k3", "v3", 2, TimeUnit.MINUTES);System.out.println("是否设置成功:"+aBoolean);//获取指定的元素String k1 = opsForValue.get("k1");System.out.println("获取指定的元素:"+k1);//自增Long k21 = opsForValue.increment("k2");System.out.println("自增1:"+k21);//自增指定长度Long k2 = opsForValue.increment("k2", 10);System.out.println("获取指定的元素:"+k2);//自减Long k22 = opsForValue.increment("k2", -1);System.out.println("获取指定的元素:"+k22);//重新赋值String andSet = opsForValue.getAndSet("k1", "vvvv");System.out.println("重新赋值:"+andSet);}
  • 关于Hash的操作——适合存放对象,操作属性方便
  1. 获取操作字符串的类对象——opsForHash
//获取操作字符串的类对象HashOperations<String, Object, Object> forHash = stringRedisTemplate.opsForHash();
  1. 存放数据——put
        //存放数据  hset(key,field,value)forHash.put("user","name","ykq");
  1. 存放map集合——putAll
        //存放mapMap<String,String> map=new HashMap<>();map.put("age","18");map.put("adrress","北京");forHash.putAll("user",map);
  1. 获取指定的元素——get
        //获取指定的元素  hget(key,field)Object o = forHash.get("user", "name");System.out.println("获取指定的元素:"+o);
  1. 获取所有的元素——entries
        Map<Object, Object> user = forHash.entries("user");System.out.println("获取所有的元素:"+user);
  1. 获取所有的key——keys
        Set<Object> user1 = forHash.keys("user");System.out.println("获取所有的key:"+user1);
  1. 获取所有的value——values
        List<Object> user2 = forHash.values("user");System.out.println("获取所有的value:"+user2);
 //关于Hash的操作@Testpublic void testHash(){//获取操作字符串的类对象HashOperations<String, Object, Object> forHash = stringRedisTemplate.opsForHash();//存放数据  hset(key,field,value)forHash.put("user","name","ykq");//存放mapMap<String,String> map=new HashMap<>();map.put("age","18");map.put("adrress","北京");forHash.putAll("user",map);//获取指定的元素  hget(key,field)Object o = forHash.get("user", "name");System.out.println("获取指定的元素:"+o);Map<Object, Object> user = forHash.entries("user");System.out.println("获取所有的元素:"+user);Set<Object> user1 = forHash.keys("user");System.out.println("获取所有的key:"+user1);List<Object> user2 = forHash.values("user");System.out.println("获取所有的value:"+user2);}

2.2 RedisTemplate

它属于StringRedisTemplate的父类,它的泛型默认都是Object。它可以直接存储任意类型的key和value

序列化

//自动注入StringRedisTemplate模板@Autowiredprivate RedisTemplate redisTemplate;@Testpublic void test1(){ValueOperations valueOperations = redisTemplate.opsForValue();//第一次存值valueOperations.set("k111","v11");//此时出现乱码,且在RedisPlus图形化工具中,并不能点击该key,显示该key不存在System.out.println(valueOperations.get("k111"));//org.springframework.data.redis.serializer.SerializationException: 会出现序列化异常,需要实体类User实现序列化接口//第二次存值valueOperations.set("k12",new User("zxy",18));//把内存中的数据存入磁盘---序列化过程}

上述代码显示的问题:

  1. 第一次存值,可以成功运行,但出现乱码,且在RedisPlus图形化工具中,并不能点击该key,显示该key不存在
  2. 第二次存值,报错:序列化异常,需要实体类User实现序列化接口

分析key出现乱码

  1. key值为乱码:所以key需要序列化,而key默认的序列化方式为JDK序列化,为二进制

  2. StringRedisTemplate类并没有出现乱码——因为他有自己的序列化方式,没有实现JDK序列化

  3. 解决:设置key的序列化方式

//设置key的序列化方式redisTemplate.setKeySerializer(new StringRedisSerializer());

此时,解决key的乱码问题,图形化界面的key可以点击查看,发现value值为乱码:

  1. value值为乱码:value默认的序列化方式也为JDK序列化JDK序列化方式需要实现序列化接口

  2. StringRedisTemplate类并没有出现乱码——因为他有自己的序列化方式,没有实现JDK序列化

  3. 解决:设置value的序列化方式

        //2. 设置value的序列化方式redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<Object>(Object.class));

使用Jackson2JsonRedisSerializer序列化的时候,如果实体类上没有set方法反序列化会报错。

  • 若使用FastJsonRedisSerializer序列化方式,需要引入fastjson依赖
<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.83</version></dependency>

如果使用RedisTemplate,每次都需要人为指定key和value的序列化,所以抽象出指定key和value序列化的工具类

  • 配置文件

    @Configuration
    public class RedisConfig {@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);ObjectMapper om = new ObjectMapper();om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);jackson2JsonRedisSerializer.setObjectMapper(om);RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();template.setConnectionFactory(redisConnectionFactory);template.setKeySerializer(jackson2JsonRedisSerializer);template.setValueSerializer(jackson2JsonRedisSerializer);template.setHashKeySerializer(jackson2JsonRedisSerializer);template.setHashValueSerializer(jackson2JsonRedisSerializer);template.afterPropertiesSet();return template;}
    }
    

2.3 集群模式

修改配置文件即可

#集群模式
spring.redis.cluster.nodes=192.168.112.189:7006,192.168.112.189:7001,192.168.112.189:7002,192.168.112.189:7003,192.168.112.189:7004,192.168.112.189:7005

2.4 二者区别

  • StringRedisTemplate和RedisTemplate的区别
  • 前者集成后者
  • 数据不共通的。即StringRedisTemplate只能管理StringRedisTemplate里面的数据,RedisTemplate只能管理RedisTemplate中的数据
  • SDR默认采用的序列化有两种。一种是String的序列化策略,一种是JDK的序列化策略;
  • StringRedisTemplate默认采用的是String 的序列化策略,保存的key和value都是采用的该策略序列化并保存的
  • RedisTemplate默认采用的是JDK的序列化策略,保存的 key和value都是采用此策略序列化并保存的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1488240.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

获取手机当前信号强度(dbm/asu值)解决 getGsmSignalStrength()总是返回99问题

能看到这篇文章说明网上哪些获取 &#xff08;dbm/asu值&#xff09;不适合你&#xff0c;不是他们的代码不正确&#xff0c;而是不符合你的情况 比如安卓6获取android手机信号强度 可以看这篇文章 https://blog.csdn.net/sinat_31057219/article/details/81134030 当然如果你…

使用Xshell进行ymodem传输时的一个小trick(用于IAP编程中的bootloader程序)

文章目录 前言三种 MCU 烧写程序的方式MCU 实现 IAP 的通用程序&#xff08;以 stm32 为例&#xff09;stm32 启动流程IAP 分区关键代码 Ymodem 协议通信信号通信流程数据帧格式 用Xshell 进行Ymodem协议传输数据调试方法一点心得 前言 这一部分主要是介绍一些背景&#xff0c…

怎样在 Nginx 中配置基于请求客户端 Wi-Fi 连接状态的访问控制?

&#x1f345;关注博主&#x1f397;️ 带你畅游技术世界&#xff0c;不错过每一次成长机会&#xff01; 文章目录 怎样在 Nginx 中配置基于请求客户端 Wi-Fi 连接状态的访问控制一、理解请求客户端 Wi-Fi 连接状态二、Nginx 中的访问控制基础知识三、获取客户端 Wi-Fi 连接状态…

使用html2canvas制作一个截图工具

0 效果 1 下载html2canvas npm install html2canvas --save 2 创建ClipScreen.js import html2canvas from html2canvas; // 样式 const cssText {box: overflow:hidden;position:fixed;left:0;top:0;right:0;bottom:0;background-color:rgba(255,255,255,0.9);z-index: 10…

vue3前端开发-小兔鲜项目-路由拦截器增加token的携带

vue3前端开发-小兔鲜项目-路由拦截器增加token的携带&#xff01;实际开发中&#xff0c;很多业务接口的请求&#xff0c;都要求必须是登录状态&#xff01;为此&#xff0c;这个token信息就会频繁的被加入到了请求头部信息中。request请求头内既然需要频繁的携带这个token.我们…

如何为 DigitalOcean 上的托管数据库收集可观测指标

DigitalOcean 在 2024 年 5 月开始支持在托管数据库&#xff08;PostgreSQL、MySQL、Redis和Kafka&#xff09;中收集可观测指标。我们将在本偏内容中&#xff0c;告诉大家如何使用部署在 DigitalOcean App Platform 上的网络应用程序&#xff0c;为 DigitalOcean 上的 Postgre…

Git的应用及码云的应用

Git 准备一台主机&#xff0c;安装应用git [rootgit ~]# yum -y install git [rootgit ~]# rpm -ql git 查看版本信息 [rootgit ~]# git [rootgit ~]# mkdir /yy000 创建目录 使用git指令&#xff0c;一定要cd到初始化之后的目录 cd到yy000目录中使用init指令促使初始化 [ro…

uniapp开发精选短视频视频小程序实战笔记20240725,实现顶部轮播图和热门短剧

创建项目 创建项目,叫video_app。 在pages.json里面修改一下标题: 新建search搜索页面和me我的页面。 此时界面预览效果如下: 引入静态资源 主要是static里面的内容,全部复制过来。 配置底部导航栏 pages.json,放到顶层,和全部样式同级: "tabBar&quo…

ChatGPT的原理和成本

ChatGPT就是人机交互的一个底层系统&#xff0c;某种程度上可以类比于操作系统。在这个操作系统上&#xff0c;人与AI之间的交互用的是人的语言&#xff0c;不再是冷冰冰的机器语言&#xff0c;或者高级机器语言&#xff0c;当然&#xff0c;在未来的十来年内&#xff0c;机器语…

Origin多个图层的层叠顺序调整

如果你有多个图层在一个图表中&#xff0c;可以在右上方的对象管理器中调整它们之间的层级关系—— 在对象管理器中处于第一位的图层&#xff0c;是层级最低的图层&#xff0c;即处于图表的最次优先显示&#xff1b;反之&#xff0c;处于最后一位的图层&#xff0c;是层级最高…

LeetCode 热题 HOT 100 (011/100)【宇宙最简单版】

【图论】No. 0200 岛屿数量 【中等】&#x1f449;力扣对应题目指路 希望对你有帮助呀&#xff01;&#xff01;&#x1f49c;&#x1f49c; 如有更好理解的思路&#xff0c;欢迎大家留言补充 ~ 一起加油叭 &#x1f4a6; 欢迎关注、订阅专栏 【力扣详解】谢谢你的支持&#xf…

C语言 | Leetcode C语言题解之第279题完全平方数

题目&#xff1a; 题解&#xff1a; // 判断是否为完全平方数 bool isPerfectSquare(int x) {int y sqrt(x);return y * y x; }// 判断是否能表示为 4^k*(8m7) bool checkAnswer4(int x) {while (x % 4 0) {x / 4;}return x % 8 7; }int numSquares(int n) {if (isPerfect…

本宫欢喜新荣记香港:米其林美学月子餐鉴赏和疗愈月子护理之旅

作为大湾区新晋“顶流”母婴护理中心和待产月子大健康解决方案提供者&#xff0c;已具备16年母婴月子专业护理经验的本宫欢喜&#xff0c;近两年备受国内和亚太备孕、待产妈妈群体和家庭珍爱。今年7月下旬&#xff0c;本宫欢喜大湾区百万影响力KOL妈妈系列体验之旅中&#xff0…

【数据结构】搜索二叉树

二叉搜索树 二叉树的博客 在之前的数据结构的文章中已经基本对二叉树有一定的了解&#xff0c;二叉搜索树也是一种数据结构&#xff0c;下面将对二叉搜索树进行讲解。 二叉搜索树的概念 二叉搜索树又称为二叉排序树&#xff0c;它或者是一棵空树&#xff0c;或者是具有下面性…

ICIP-2020-A Non-local Mean Temporal Filter for VideoCompression

在 libvpx、VP8、VP9 和 HEVC 等各种编码器实现中&#xff0c;早就发现在预处理阶段过程中从源视频信号去除噪声对客观压缩效率的提升存在好处。通常使用常规的块匹配运动搜索来构建运动轨迹&#xff0c;并沿着轨迹比较每对像素&#xff0c;根据像素间的差异确定时域滤波器系数…

网络原理_初识

目录 一、局域网LAN 二、广域网WAN 三、网络通信基础 3.1 IP地址 3.2 端口号 3.3 协议 3.4 五元组 3.5 OSI七层模型 3.6 TCP/IP五层模型 3.7 网络设备所在分层 3.8 封装和分用 总结 一、局域网LAN 局域网&#xff0c;即 Local Area Network&#xff0c;Local 即标…

Godot游戏制作 05收集物品

创建新场景&#xff0c;添加Area2D节点&#xff0c;AnimatedSprite2D节点 &#xff0c;CollisionShape2D节点 添加硬币 按F键居中&#xff0c;放大视图。设置动画速度设为10FPS&#xff0c;加载后自动播放&#xff0c;动画循环 碰撞形状设为圆形&#xff0c;修改Area2D节点为Co…

看2024如何利用IT项目管理软件实现项目稳定输出,创造价值

曾经做为一个在大型互联网公司工作了10年的项目实施工作人员来讲&#xff0c;亲眼见证了IT项目管理软件的兴起和发展&#xff0c;也深刻体会到它在提升项目效率和管理水平方面的巨大价值。它就像一把神奇的钥匙&#xff0c;打开了项目管理的新世界&#xff0c;让原本混乱无序的…

docer笔记3

docker笔记3 容器基本命令 容器基本命令 下载镜像 docker pull cento新建容器并启动 docker run [可选参数] image# 参数说明 --name“Name” 容器名字 tomcat01 tomcat02 用来区分容器 -d 后台方式运行 -it 使用交互方式运行&#xff0c;进入容器查…

leetcode3098. 求出所有子序列的能量和

官解 class Solution(object):# 定义常量mod int(1e9 7) # 模数&#xff0c;用于防止结果溢出inf float(inf) # 无穷大&#xff0c;用于初始化时的特殊值def sumOfPowers(self, nums, k):n len(nums) # 数组长度res 0 # 用于存储最终结果# 三维动态规划表&#xff0c;…