SpringBoot - 整合Redis:使用Jedis客户端

Jedis

Redis与Mysql都是数据库,Redis是非关系型数据库,Mysql是关系型数据库

对于关系型数据库存在Java的数据库连接:JDBC
Jedis就类似于JDBC,是Redis官方首选的Java客户端开发包,Jedis就是集成了redis的一些命令操作,封装了redis的java客户端

我们可以写一个简单的Jedis命令:

  1. 需要导入Jedis的jar包
        <!--Jedis依赖-->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
        </dependency>
  1. 打开Redis数据库,存放一个name:lisi数据

SpringBoot - 整合Redis:使用Jedis客户端_第1张图片

  1. 调用Jedis连接Redis
    @Test
    void test4(){
        Jedis jedis = new Jedis("localhost",6379);
        String name = jedis.get("name");

        System.out.println(name);
        jedis.close();
    }

很简单的就完成了数据库操作:
SpringBoot - 整合Redis:使用Jedis客户端_第2张图片

Jedis集成了redis的一些命令操作,封装了redis的java客户端,从它的方法也可以看出:都是Redis的命令
SpringBoot - 整合Redis:使用Jedis客户端_第3张图片

每个Jedis实例对应一个Redis节点,Jedis实例的操作相当于启动redis-cli客户端操作


JedisPool

就如同我们不会直接使用JDBC连接数据库,而是使用数据库连接池如dbcp、c3p0等

Jedis也为我们提供了Jedis的池化技术,JedisPool在创建时初始化一些连接资源存储到连接池中,使用Jedis连接资源时不需要创建,而是从连接池中获取一个资源进行redis的操作,使用完毕后,不需要销毁该jedis连接资源,而是将该资源归还给连接池,供其他请求使用

JedisPool类提供了很多构造方法,用于设置连接池的属性

SpringBoot - 整合Redis:使用Jedis客户端_第4张图片

GenericObjectPoolConfig配置类用于封装连接池属性:最大空闲数、最大连接数等

后续参数有:host地址,port端口号,timeout超时时间,password数据库密码等
SpringBoot - 整合Redis:使用Jedis客户端_第5张图片

通过这些参数连接Redis,配置连接池参数,可以使连接池有效的管理Redis连接


SpringBoot整合Redis

项目:因为这里只整合Redis,即只使用config配置类,User实体类,service服务层,Redis做缓存用

SpringBoot - 整合Redis:使用Jedis客户端_第6张图片

在applicat.yml中可以设置Jedis:

spring:
  redis:
    host: ip地址
    password: 密码
    port: 6379
    timeout: 20000 #超时连接
    jedis:
      pool:
        max-idle: 6 #最大空闲数
        max-active: 10 #最大连接数
        min-idle: 2 #最小空闲数

Spring也提供了很多Redis的配置:

SpringBoot - 整合Redis:使用Jedis客户端_第7张图片

以及Jedis配置:

SpringBoot - 整合Redis:使用Jedis客户端_第8张图片

我们需要获得这些属性封装到配置类中,返回bean:JedisPool

package com.learn.jedis.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

/**
 * Author : zfk
 * Data : 17:28
 */
@Configuration
public class JedisConfig {

    private Logger logger = LoggerFactory.getLogger(JedisConfig.class);

    @Value("${spring.redis.host}")
    private String host;
    @Value("${spring.redis.port}")
    private int port;
    @Value("${spring.redis.password}")
    private String password;
    @Value("${spring.redis.timeout}")
    private int timeout;
    @Value("${spring.redis.jedis.pool.max-idle}")
    private int maxIdle;
    @Value("${spring.redis.jedis.pool.max-active}")
    private int maxActive;
    @Value("${spring.redis.jedis.pool.min-idle}")
    private int minIdle;

    @Bean
    public JedisPool jedisPool(){
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxIdle(maxIdle);
        jedisPoolConfig.setMaxTotal(maxActive);
        jedisPoolConfig.setMinIdle(minIdle);

        JedisPool jedisPool = new JedisPool(jedisPoolConfig, host, port, timeout, password);

        logger.info("JedisPoll连接成功:"+host+"\t"+port);

        return jedisPool;

    }
}

实体类:

package com.learn.jedis.po;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
 * Author : zfk
 * Data : 17:20
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {
    private String id;
    private String name;
    private Integer age;

}

对应Redis中Hash类型的数据:user:1 {id:1,name:lisi,age:26}

SpringBoot - 整合Redis:使用Jedis客户端_第9张图片

服务层UserService:

package com.learn.jedis.service;

import com.learn.jedis.po.User;

/**
 * Author : zfk
 * Data : 19:37
 */
public interface UserService {
    public User selectById(String id);
}

UserServiceImpl:

package com.learn.jedis.service;

import com.learn.jedis.po.User;
import lombok.extern.java.Log;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import java.util.HashMap;
import java.util.Map;


/**
 * Author : zfk
 * Data : 19:40
 */
@Service
@Log
public class UserServiceImpl implements UserService {



    //Redis - Jedis连接池
    @Autowired
    private JedisPool jedisPool;

    /**
     * Redis - Hash类型
     * 存一个对象
     * 用户在前端传入一个ID编号,查询用户对象
     * 先到Redis查询,如果Redis存在直接返回结果
     * 不存在就查询Mysql(模拟),返回查询结果,赋值给Redis
     */
    @Override
    public User selectById(String id){
        //key => 表名:id
        String key ="user:"+id;
        //得到Jedis对象
        Jedis jedis = jedisPool.getResource();

        User user = null;
        //判断
        if (jedis.exists(key)){
            //存在,打印输出
            log.info("=== 查询Redis数据库 ===");
            Map<String, String> map = jedis.hgetAll(key);
            user = new User(map.get("id"), map.get("name"), Integer.parseInt(map.get("age")));
        }
        else {
            log.info("=== 查询Mysql数据库 ===");
            user = new User(id,"张三",19);
            HashMap<String, String> map = new HashMap<>();
            map.put("id",user.getId());
            map.put("name",user.getName());
            map.put("age",user.getAge().toString());
            jedis.hmset(key,map);
            log.info("=== 存入Redis中 ===");

        }
        return user;
    }

测试类:

package com.learn.jedis;

import com.learn.jedis.po.User;
import com.learn.jedis.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

@SpringBootTest
class JedisApplicationTests {
    @Autowired
    private UserService userService;
    @Test
    void test3(){
        User user = userService.selectById("1111");
        System.out.println(user.toString());
    }
}

第一次查询id=1111的用户,不存在,赋值给Redis

在这里插入图片描述

第二次查询Redis存在,返回结果:
在这里插入图片描述


代码

码云

SpringBoot - 整合Redis:使用Jedis客户端_第10张图片


其他Redis客户端工具

Jedis现在只在比较老的项目上了

SpringBoot2.x起,默认使用Lettuce

Lettuce 和 Jedis 都是Redis的client:redis-cli
Jedis在实现上是直接连接的Redis Server,如果在多线程环境下是非线程安全的。 每个线程都去拿自己的 Jedis 实例,当连接数量增多时,资源消耗阶梯式增大,连接成本就较高了。

Lettuce的连接是基于Netty的,Netty 是一个多线程、事件驱动的 I/O框架。连接实例可以在多个线程间共享,当多线程使用同一连接实例时,是线程安全的。

你可能感兴趣的:(Redis,SpringBoot)