[Redis 客戶端整合] SpringBoot 整合 Jedis

DavidH發表於2024-11-22

一、簡介

​ 在使用SpringBoot搭建微服務的時候, 很多時候需要用Redis來快取一些資料 , 儲存一些高頻率訪問的資料。SpringBoot整合Redis所常用的Redis常用客戶端有三個:

  • Jedis api
  • redisson
  • lettuce

本文使用Jedis來實現Redis訪問

二、匯入依賴

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
</dependency>

三、配置連線資訊

application.yml檔案中, 配置 Redis 連線資訊

spring:
  redis:
    port: 6379
    password: 123456
    host: 127.0.0.1
    jedis:
      pool:
        max-idle: 6 #最大空閒數
        max-active: 10 #最大連線數
        min-idle: 2 #最小空閒數
    timeout: 2000 #超時連線

四、編寫JedisConfig

建立類: com.learning.config.jedis.JedisConfig

@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.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;

    @Value("${spring.redis.timeout}")
    private int timeout;

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

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

        logger.info("JedisPool連線成功:"+ host + "\t" + port);

        return jedisPool;
    }
}

註釋:

可以直接使用 Jedis()建構函式來連線Redis資料庫 , 我們使用連線池 , 來對其進行最佳化 。例如 :

String host = "127.0.0.1";
int port = 6379;
Jedis jedis = new Jedis(host, port);
jedis.auth("123456");
    
jedis.方法();

jedis.close();

五、使用Jedis

(1)注入 JedisPool 物件

在要使用 Jedis 的類中注入 JedisPool 物件

 @Autowired
private JedisPool jedisPool;

JedisPool 的 Bean 物件是在JedisConfig類中宣告的 :

@Bean
public JedisPool jedisPool(){
	......
	return jedisPool;
}

(2)使用Jedis

1.得到 Jedis 物件

在方法中, 透過 jedisPool 物件得到 Jedis 物件

//得到jedis物件
Jedis jedis = jedisPool.getResource();

2.使用 jedis 物件操作Redis

Redis 中有什麼語法, jedis 物件就有什麼方法 , 例如查詢 Key是否存在:

jedis.exists("Key")

3.關閉連線

在使用完 jedis 物件後, 一定要記得關閉連線

jedis.close();

(3)例項 - Jedis操作 String 型別

透過 key 來得到 String 型別的 value

如果 Redis 中存在 key 則從Redis中獲得 , 如果不存在 , 則到Mysql資料庫中查詢 , 再賦給Redis

    public String getString(String key) {
        //得到jedis物件
        Jedis jedis = jedisPool.getResource();
        String val = null;
        //判斷redis中key是否存在
        if(jedis.exists(key)){
            val = jedis.get(key);
            log.info("查詢Redis中的資料");
        }else{
            val = "模擬從mysql查到的資料";
            log.info("查詢mysql中的資料");
            jedis.set(key,val);
        }
        //關閉連線
        jedis.close();
        return val;
    }

(4)例項 - Jedis操作 Hash 型別

透過 key 來得到 User 型別的 物件

如果 Redis 中存在 key 則從Redis中獲得 , 如果不存在 , 則到Mysql資料庫中查詢 , 再賦給Redis

User物件

@Data
public class User implements Serializable {
    private String id;
    private String name;
    private Integer age;
}

查詢方法

public User selectUserById(String Id){
        String key = "user:" + Id;
    
        //得到jedis物件
        Jedis jedis = jedisPool.getResource();
    
        User resultUser = new User();
        Map<String,String> resultMap = new HashMap<String,String>();
        if(jedis.exists(key)){
            resultMap = jedis.hgetAll(key);
            log.info("從Redis中查詢");
            String id = resultMap.get("id");
            String name = resultMap.get("name");
            Integer age = Integer.parseInt(resultMap.get("age"));
            resultUser.setId(id);
            resultUser.setName(name);
            resultUser.setAge(age);
        }else{
            //模擬從Mysql資料庫查詢到資料
            resultUser.setId(Id);
            resultUser.setName("張三");
            resultUser.setAge(20);
            resultMap.put("id",resultUser.getId());
            resultMap.put("name",resultUser.getName());
            resultMap.put("age",resultUser.getAge() + "");
            log.info("從Mysql中查詢");
            jedis.hmset(key,resultMap);
        }
    
    //關閉連線
    jedis.close();
    
    return resultUser;
}

六、建立Jedis工具類

在開發中, 我們可以建立一個Jedis工具類, 來對Jedis進行進一步的封裝, 讓其實現更多的功能

例如 : 透過Jedis工具類來實現Jedis的獲取和關閉

@Component
public class JedisUtil {

    @Autowired
    private JedisPool jedisPool;

    public <T> T useJedis(Function<Jedis, T> function){
        Jedis jedis = jedisPool.getResource();
        T result = function.apply(jedis);
        jedis.close();
        return result;
    }

}

在此時, 在一個類中, 若想使用Jedis , 就無需再注入JedisPool物件了, 而是注入Jedis工具類

    @Autowired
    private JedisUtil jedisUtil;

jedisUtiluseJedis()方法中, 建立一個匿名類, 來實現功能 :

/**
* 透過 key 來得到 String 型別的 value
* 如果 Redis 中存在 key 則從Redis中獲得 , 如果不存在 , 則到Mysql資料庫中查詢 , 再賦給Redis
*/
public String getString(String key) {

    String result = jedisUtil.useJedis(new Function<Jedis, String>() {
        @Override
        public String apply(Jedis jedis) {

            String val = null;
            //判斷redis中key是否存在
            if(jedis.exists(key)){
                val = jedis.get(key);
                log.info("查詢Redis中的資料");
            }else{
                val = "模擬從mysql查到的資料";
                log.info("查詢mysql中的資料");
                jedis.set(key,val);
            }
            return val;
        }
    });

    return result;
}

相關文章