Java连接Redis和SpringBoot整合Redis

news2024/12/23 6:08:53

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);
        //设置一个map
        Map<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
        //设置一个map
        Map<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项目操作redis

java提高连接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);
        //设置一个map
        Map<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
        //设置一个map
        Map<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();//操作hash
     stringRedisTemplate.opsForList();//操作列表
     stringRedisTemplate.opsForSet();//操作无序集合
     stringRedisTemplate.opsForZSet();//操作有序集合——有序是score的有序
  • 关于key的操作
  1. 获取所有的key——keys
//获取所有的key
        Set<String> keys = stringRedisTemplate.keys("*");
        System.out.println("所有的key:"+keys);

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

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

返回值为boolean

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

返回值为boolean

  1. 是否设置过期时间——expire
        //设置过期时间——返回值为boolean
        Boolean 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的操作
    @Test
    void testKeys() {
        //获取所有的key
        Set<String> keys = stringRedisTemplate.keys("*");
        System.out.println("所有的key:"+keys);
        //删除指定的key——返回值为boolean
        Boolean k1 = stringRedisTemplate.delete("k1");
        System.out.println("是否删除指定的k1:"+k1);
        //判断指定的key是否存在——返回值为boolean
        Boolean k11 = stringRedisTemplate.hasKey("k1");
        System.out.println("是否存在k1:"+k11);
        //设置过期时间——返回值为boolean
        Boolean 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类对应每种数据类型的操作 对应相应的类来完成
    @Test
    void 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
        //存放map
        Map<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的操作
    @Test
    public void testHash(){
        //获取操作字符串的类对象
        HashOperations<String, Object, Object> forHash = stringRedisTemplate.opsForHash();
        //存放数据  hset(key,field,value)
        forHash.put("user","name","ykq");
        //存放map
        Map<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模板
    @Autowired
    private RedisTemplate redisTemplate;

    @Test
    public 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 {
        @Bean
        public 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.coloradmin.cn/o/1948798.html

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

相关文章

Linux---01---安装VMware

一. 什么时Linux Linux 是一个开源的类 Unix 操作系统,Linux 是许多计算机硬件的底层操作系统&#xff0c;特别是服务器、嵌入式系统和个人电脑。它支持多种架构&#xff0c;包括 x86、x64、ARM 和 MIPS 等。Linux 因其稳定性、安全性、开源性以及广泛的社区支持而广受欢迎。 …

《人工智能大语言模型技术发展研究报告(2024)》【下载】

《人工智能大语言模型技术发展研究报告&#xff08;2024&#xff09;》下载 自2023年起&#xff0c;大模型技术产品的快速迭代和升级&#xff0c;已经成为全球科技竞争的关键因素。由中国软件评测中心发布的《人工智能大语言模型技术发展研究报告&#xff08;2024&#xff09;》…

安卓开机启动性能优化之-bootchart相关工具使用及查看

背景&#xff1a; 开机启动相关的详细信息&#xff0c;一般都是可以通过logcat中查看boot_progress相关查看&#xff0c;这种方式查看相对不那么方便&#xff0c;毕竟开机过程中涉及的进程较多&#xff0c;要查看也较多&#xff0c;而且还经常需要查看代码才可以对应起来&…

Vue3时间选择器datetimerange在数据库存开始时间和结束时间

♥️作者&#xff1a;小宋1021 &#x1f935;‍♂️个人主页&#xff1a;小宋1021主页 ♥️坚持分析平时学习到的项目以及学习到的软件开发知识&#xff0c;和大家一起努力呀&#xff01;&#xff01;&#xff01; &#x1f388;&#x1f388;加油&#xff01; 加油&#xff01…

C++知识点:类和对象(自用)

类和对象 1. 类和对象的关系2. 对象指针3. 在堆上创建对象4. 成员访问限定符5. 名字编码&#xff08;Name Mangling&#xff09;6.构造函数7.构造函数的重载8.初始化列表8. 成员变量初始化的顺序&#xff08;通过初始化列表&#xff09;9. 初始化 const 成员变量10. 析构函数11…

【Web爬虫逆向】“企业预警通”模糊查询公司信息,逆向案例实战

“企业预警通”模糊查询公司信息&#xff0c;逆向案例实战 功能介绍效果演示思路分析1、先找到模糊查询的接口2、分析headers与params中参数并进行构造3、JS逆向&#xff0c;跟栈&#xff0c;找到js中key和dataCategory的生成方法&#xff0c;并完成js补码构造4、成功还原key后…

嵌入式中什么是三次握手

在开始前刚好我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「嵌入式的资料从专业入门到高级教程」&#xff0c;点个关注在评论区回复“666”之后私信回复“666”&#xff0c;全部无偿共享给大家&#xff01;&#xff01;&#xff01; 在网络数据传输中&#xf…

Mysql的主从复制(重要)和读写分离(理论重要实验不重要)

一、主从复制&#xff1a;架构一般是一主两从。 1.主从复制的模式&#xff1a; mysql默认模式为异步模式&#xff1a;主库在更新完事务之后会立即把结果返回给从服务器&#xff0c;并不关心从库是否接收到以及从库是否处理成功。缺点&#xff1a;网络问题没有同步、防火墙的等…

论文阅读:Deep_Generic_Dynamic_Object_Detection_Based_on_Dynamic_Grid_Maps

目录 概要 Motivation 整体框架流程 技术细节 小结 不足 论文地址&#xff1a;Deep Generic Dynamic Object Detection Based on Dynamic Grid Maps | IEEE Conference Publication | IEEE Xplore 概要 该文章提出了一种基于动态网格图&#xff08;Dynamic Grid Maps&a…

DevExpress WPF中文教程:如何完成GridControl的列和编辑器配置?

DevExpress WPF拥有120个控件和库&#xff0c;将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpress WPF能创建有着强大互动功能的XAML基础应用程序&#xff0c;这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。 无论是Office办公软件…

基于微信小程序的校园警务系统/校园安全管理系统/校园出入管理系统

摘要 伴随着社会以及科学技术的发展&#xff0c;小程序已经渗透在人们的身边&#xff0c;小程序慢慢的变成了人们的生活必不可少的一部分&#xff0c;紧接着网络飞速的发展&#xff0c;小程序这一名词已不陌生&#xff0c;越来越多的学校机构等都会定制一款属于自己个性化的小程…

Exponential Moving Average (EMA) in Stable Diffusion

1.Moving Average in Stable Diffusion (SMA&EMA) 1.Moving average 2.移动平均值 3.How We Trained Stable Diffusion for Less than $50k (Part 3) Moving Average 在统计学中&#xff0c;移动平均是通过创建整个数据集中不同选择的一系列平均值来分析数据点的计算。 …

树莓集团——缔造国际领先的数字媒体产业孵化基地

在数字化浪潮席卷全球的背景下&#xff0c;树莓集团以其卓越的创新能力&#xff0c;正在全力打造一个全球领先的数字媒体产业基地。成都国际数字影像产业园不仅是技术和创意的汇聚地&#xff0c;更是数字内容创新与应用的典范&#xff0c;推动数字媒体产业迈向新的高度。 树莓集…

vue.js入门

目录 一. 框架概述 二. vue常用命令 2.1 插值表达式 2.2 v-text 2.3 v-html 2.4 v-on 2.5 v-model 2.6 v-show 2.7 v-if 2.8 v-else 2.9 v-bind 2.10 v-for 三. vue生命周期函数 一. 框架概述 我们之前写的javaScript代码都是原生的,而框架是在基础语言之上,对其进…

pytorch-梯度下降

梯度下降 y x 2 ∗ s i n ( x ) y ′ 2 x s i n x x 2 c o s x x 1 x − Δ y ′ ( x ) 其中 Δ 表示学习率&#xff0c; y ′ ( x ) 代表 y 在 x 点处关于 x 的梯度。 y x^2 * sin(x) \\ y 2xsinxx^2cosx \\ x_1 x - \Delta y(x) \\ 其中 \Delta 表示学习率&#xff0c…

qt表格模型视图

Qt 提供了一套强大的模型/视图框架&#xff0c;允许你以一种非常灵活和高效的方式显示和处理数据。在 Qt 中&#xff0c;表格视图&#xff08;TableView&#xff09;和模型&#xff08;TableModel&#xff09;是这种框架的一部分&#xff0c;常用于显示和编辑表格数据。 以下是…

便携式气象仪:科技赋能,让气象观测更智能

随着科技的快速发展&#xff0c;越来越多的领域受益于技术的进步。其中&#xff0c;气象观测领域也不例外。传统的气象观测设备虽然精确可靠&#xff0c;但往往体积庞大、携带不便&#xff0c;且需要专业人员进行操作和维护。而便携式气象仪的出现&#xff0c;则打破了这一局限…

BGP路由反射器

原理概述 缺省情况下&#xff0c;路由器从它的一个 IBGP对等体那里接收到的路由条目不会被该路由器再传递给其他IBGP对等体&#xff0c;这个原则称为BGP水平分割原则&#xff0c;该原则的根本作用是防止 AS内部的BGP路由环路。因此&#xff0c;在AS内部&#xff0c;一般需要每台…

深度解读大语言模型中的Transformer架构

一、Transformer的诞生背景 传统的循环神经网络&#xff08;RNN&#xff09;和长短期记忆网络&#xff08;LSTM&#xff09;在处理自然语言时存在诸多局限性。RNN 由于其递归的结构&#xff0c;在处理长序列时容易出现梯度消失和梯度爆炸的问题。这导致模型难以捕捉长距离的依…

《知识点扫盲 · Redis 序列化器》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; CSDN入驻不久&#xff0c;希望大家多多支持&#xff0c;后续会继续提升文章质量&#xff0c;绝不滥竽充数…