Redis 之Jedis 加springboot整合Redis

Jedis

API 文档

在线文档: https://www.mklab.cn/onlineapi/jedis/

Jedis 介绍

Jedis 工作示意图

Java 程序操作Redis 的工具

示意图

Redis 之Jedis 加springboot整合Redis_第1张图片

Jedis 操作Redis 数据

快速入门

  1. 创建maven 项目
    Redis 之Jedis 加springboot整合Redis_第2张图片

Redis 之Jedis 加springboot整合Redis_第3张图片

注意二步是路径配置自己想放哪里 三步是 定义包的层次结构 嫌弃麻烦的也可以不设置 然后确认就可以了

Redis 之Jedis 加springboot整合Redis_第4张图片

  1. 修改pom.xml , 增加依赖
<dependencies>
    <dependency>
        <groupId>redis.clientsgroupId>
        <artifactId>jedisartifactId>
        <version>3.2.0version>
    dependency>
dependencies>
  1. 创建Jedis_.java
public class Jedis_ {

    //连接Redis
    //1. 如果Redis配置了密码,则需要进行身份校验
    //2. 因为需要连接到redis端口,比如6379, 就需要配置防火墙,放开端口
    //3. 注意修改bind,支持远程连接.
    @Test
    public void con() {

        Jedis jedis = new Jedis("192.168.198.135", 6379);

        jedis.auth("foobared");
        String res = jedis.ping();
        System.out.println("连接成功 ping 返回结果=" + res);
        jedis.close();//关闭当前连接,注意并没有关闭Redis
    }

    //key操作
    @Test
    public void key() {

        Jedis jedis = new Jedis("192.168.198.135", 6379);

        jedis.auth("foobared");
        //设置key
        jedis.set("k1", "v1");
        jedis.set("k2", "v2");
        jedis.set("k3", "v3");

        //获取key
        Set<String> keys = jedis.keys("*");

        for (String key : keys) {
            System.out.println("key==>" + key);
        }

        //判断key是否存在,ttl
        System.out.println(jedis.exists("k1"));//T
        System.out.println(jedis.ttl("k2"));//-1
        System.out.println(jedis.get("k3"));//v3

        //关闭连接
        jedis.close();

    }

    //string
    @Test
    public void string() {

        Jedis jedis = new Jedis("192.168.198.135", 6379);

        jedis.auth("foobared");
        //批量设置k-v
        jedis.mset("k1", "jack", "k2", "scott", "k3", "hsp");
        //批量获取v
        List<String> mget = jedis.mget("k1", "k2");
        for (String s : mget) {
            System.out.println("s-->" + s);
        }
        jedis.close();
    }

    //list
    @Test
    public void list() {
        Jedis jedis = new Jedis("192.168.198.135", 6379);
        jedis.auth("foobared");
        //添加list数据
        jedis.lpush("name_list", "jack", "tom", "nono");
        List<String> name_list = jedis.lrange("name_list", 0, -1);
        for (String name : name_list) {
            System.out.println("name--->" + name);
        }
        //关闭连接
        jedis.close();
    }

    //set
    @Test
    public void set() {

        Jedis jedis = new Jedis("192.168.198.135", 6379);
        jedis.auth("foobared");

        jedis.sadd("city", "北京", "上海");
        jedis.sadd("city", "广州");
        jedis.sadd("city", "深圳");

        Set<String> smembers = jedis.smembers("city");
        for (String city : smembers) {
            System.out.println("city-->" + city);
        }
        jedis.close();
    }

    //hash
    @Test
    public void hash() {

        Jedis jedis = new Jedis("192.168.198.135", 6379);
        jedis.auth("foobared");

        //设置
        jedis.hset("hash01", "name", "李白");
        jedis.hset("hash01", "age", "30");


        //获取
        String name = jedis.hget("hash01", "name");
        System.out.println("name=>" + name);

        //先构建一个map,然后加入
        Map<String, String> maps = new HashMap<String, String>();
        maps.put("job", "java工程师");
        maps.put("name", "smith");
        maps.put("email", "[email protected]");
        jedis.hset("hash02", maps);

        //取出看看
        List<String> person =
                jedis.hmget("hash02", "job", "name", "email");
        for (String s : person) {
            System.out.println("s===>" + s);
        }


        jedis.close();

    }

    //zset-有序集合
    @Test
    public void zset() {

        Jedis jedis = new Jedis("192.168.198.135", 6379);
        jedis.auth("foobared");

        //添加
        jedis.zadd("hero", 1, "关羽");
        jedis.zadd("hero", 2, "张飞");
        jedis.zadd("hero", 5, "黄忠");
        jedis.zadd("hero", 3, "赵云");
        jedis.zadd("hero", 4, "马超");


        //取出
        Set<String> heroes = jedis.zrange("hero", 0, -1);//按照评分从小到大
        //Set heroes = jedis.zrevrange("hero", 0, -1);//按照评分从大到小
        for (String hero : heroes) {
            System.out.println("hero= " + hero);
        }
        jedis.close();
    }
}

连接Redis 注意事项

1、确保ip:6379 是连通的, 注意打开防火墙的6379 端口

● 设置开放的端口号

​ firewall-cmd --add-port=6379/tcp --permanent
● 重启防火墙

​ firewall-cmd --reload
● 查看防火墙

​ firewall-cmd --list-all

Redis 之Jedis 加springboot整合Redis_第5张图片

2、如果redis 你设置了密码, 需要执行jedis.auth(“密码”);进行权限验证

Spring Boot2 整合Redis

需求分析/图解

  1. 在springboot 中, 整合redis
  2. 可以通过RedisTemplate 完成对redis 的操作, 包括设置数据/获取数据
  3. 比如添加和读取数据

在这里插入图片描述

注意redis存储汉字是以16进制存储的

在这里插入图片描述

具体整合实现

创建maven web 项目

流程和上面一样这里就不截图了

修改pom.xml - 引入相关依赖


<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0modelVersion>
    <parent>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-parentartifactId>
        <version>2.6.6version>
        <relativePath/> 
    parent>
    <groupId>com.hspedugroupId>
    <artifactId>redis_springbootartifactId>
    <version>1.0-SNAPSHOTversion>
    <name>redis_springbootname>
    <description>Demo project for Spring Bootdescription>
    <properties>
        <java.version>1.8java.version>
    properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>

        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-data-redisartifactId>
        dependency>

        
        <dependency>
            <groupId>org.apache.commonsgroupId>
            <artifactId>commons-pool2artifactId>
            
        dependency>

        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>
            <scope>testscope>
        dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.coregroupId>
            <artifactId>jackson-databindartifactId>
            <version>2.13.2.2version>
        dependency>

    dependencies>


    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-maven-pluginartifactId>
            plugin>
        plugins>
    build>

project>

配置

application.properties

– 完成redis 的基本配置

#Redis 服务器地址
spring.redis.host=192.168.198.130
#Redis 服务器连接端口
spring.redis.port=6379
#Redis 如果有密码,需要配置, 没有密码就不要写
spring.redis.password=hspedu
#Redis 数据库索引(默认为0)
spring.redis.database=0
#连接超时时间(毫秒)
spring.redis.timeout=1800000
#连接池最大连接数(使用负值表示没有限制)
spring.redis.lettuce.pool.max-active=20
#最大阻塞等待时间(负数表示没限制)
spring.redis.lettuce.pool.max-wait=-1
#连接池中的最大空闲连接
spring.redis.lettuce.pool.max-idle=5
#连接池中的最小空闲连接
spring.redis.lettuce.pool.min-idle=0

redis 配置类

1、是对要使用的RedisTemplate bean 对象的配置, 可以理解成是一个常规配置.

2、这个和 Spring中的JdbcTemplate,设计理念类似 如果感兴趣可以去专栏主流框架里面的JdbcTemplate博客看看

3、如果不配置, springboot 会使用默认配置, 这个默认配置, 会出现一些问题, 比如:redisTemplate 的key 序列化等, 问题所以通常我们需要配置

4、创建config\RedisConfig.java

@EnableCaching
@Configuration
public class RedisConfig extends CachingConfigurerSupport {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template =
                new RedisTemplate<>();
        System.out.println("template=>" + template);//这里可以验证..
        RedisSerializer<String> redisSerializer =
                new StringRedisSerializer();
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer =
                new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.activateDefaultTyping(
                LaissezFaireSubTypeValidator.instance,
                ObjectMapper.DefaultTyping.NON_FINAL,
                JsonTypeInfo.As.WRAPPER_ARRAY);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        template.setConnectionFactory(factory);
        //key序列化方式
        template.setKeySerializer(redisSerializer);
        //value序列化
        template.setValueSerializer(jackson2JsonRedisSerializer);
        //value hashmap序列化
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        return template;
    }

    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        RedisSerializer<String> redisSerializer =
                new StringRedisSerializer();
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        //解决查询缓存转换异常的问题
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.activateDefaultTyping(
                LaissezFaireSubTypeValidator.instance,
                ObjectMapper.DefaultTyping.NON_FINAL,
                JsonTypeInfo.As.WRAPPER_ARRAY);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        // 配置序列化(解决乱码的问题),过期时间600秒
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofSeconds(600))
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
                .disableCachingNullValues();
        RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
                .cacheDefaults(config)
                .build();
        return cacheManager;
    }
}

注意事项和细节

1、如果没有提供RedisConfig 配置类, springboot 会使用默认配置, 也可以使用下面测试方法的t3方法先不注销请求看看 然后在注销看看就可以验证了

Redis 之Jedis 加springboot整合Redis_第6张图片

2、如果没有提供RedisConfig 配置类, springboot 会使用默认配置, 但是会存在问题,比如redisTemplate 模糊查找key 数据为空

Redis 之Jedis 加springboot整合Redis_第7张图片

3、Unrecognized token ‘beijing’: was expecting (‘true’, ‘false’ or ‘null’)看报错,是jason 转换异常,实际上是因为redisTemplate 在做数据存储的时候会把存储的内容序列化,所以,redisTemplate 读取的时候也会反序列化,而在redis 客户端set 的时候并不会做序列化,因此set 的进去的值在用redisTemplate 读的时候就会报类型转换异常了 这个可以使用下面测试 t2 和t4 来验证 如果直接请求t4会报下面的错误 但是如果我们先请求t3 在请求t4就不会报错

Redis 之Jedis 加springboot整合Redis_第8张图片

4、解决方案: 最简单的就是用程序重新set 一遍即可 就是执行一次set语句 然后在get

控制器-提供API 接口

@RestController
@RequestMapping("/redisTest")
public class RedisTestController {

     //编写第一个测试方法
    //演示设置数据和获取数据
    @GetMapping("/t1")
    public String t1() {

        //设置值到redis
        redisTemplate.opsForValue().set("book", "天龙八部~");
        //从redis获取值
        String book = (String) redisTemplate.opsForValue().get("book");
        return book;
    }

    //编写方法,演示如何操作list,hash,set,zset
    @GetMapping("/t2")
    public String t2() {
        //list-存
        redisTemplate.opsForList().leftPush("books", "笑傲江湖");
        redisTemplate.opsForList().leftPush("books", "hello,java");

        //list-取出
        List books = redisTemplate.opsForList().range("books", 0, -1);
        String booksList = "";
        for (Object book : books) {
            System.out.println("book-->" + book.toString());
            booksList += book.toString() + " ";
        }
        //hash
        //redisTemplate.opsForHash()
        //set
        //redisTemplate.opsForSet()
        //zset
        //redisTemplate.opsForZSet()
        return booksList;
    }

    //编写一个方法,获取所有的key
    @GetMapping("/t3")
    public String t3() {
        Set keys = redisTemplate.keys("*");
        for (Object key : keys) {
            System.out.println("key--->" + key.toString());
        }
        return "OK";
    }


    //编写方法,获取通过客户端添加的数据-会出现异常
    //需要保持一致,比如RedisTemplate读取的数据,应当是RedisTemplate存放的数据
    @GetMapping("/t4")
    public String t4() {

        String val = (String) redisTemplate.opsForValue().get("book");

        System.out.println("val= " + val);

        return val;
    }


}

2、说明: 可以通过debug/输出对象, 验证该文件的redisTemplate 对象, 就是配置类RedisConfig 的Bean redisTemplate, 并且已经进行了相关序列化的配置.

你可能感兴趣的:(中间件,redis,spring,boot,java,jedis,缓存)