Springboot整合lettuce并优化代码

优化前

添加pom依赖

<!--        默认是lettuce客户端-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
<!--        redis依赖commons-pool-->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>

修改yml文件

server:
  port: 8080
spring:
  redis:
    port: 6379
    #    password:
    host: 192.168.214.128
    lettuce:
      pool:
        max-active: 8  #连接池最大连接数(使用负数表示没有限制)
        max-idle: 6   #连接池最大空闲数
        min-idle: 2   #连接池最小空闲数
        max-wait: 1000 #连接池最大阻塞等待时间(使用负值表示没有限制)
      shutdown-timeout: 100 #关闭超时时间

添加实体类

package com.yang.pojo;

import java.io.Serializable;

/**
 * Description:
 * date: 2020/7/4 21:09
 *
 * @author Crille-g
 * @version 1.0
 */

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

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", id='" + id + '\'' +
                ", age=" + age +
                '}';
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

创建配置类(数据保存在redis中时,要进行序列化,默认使用JDK进行数据序列化)

package com.yang.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
 * Description:
 * date: 2020/7/4 21:55
 *
 * @author Crille-g
 * @version 1.0
 */
@Configuration
public class RedisConfig {
    /**
     * Spring data 提供了RedisTemplate模板
     * 模板封装了redis连接池管理的逻辑,业务代码不需要关心获取\释放连接逻辑;
     * spring redis 同时支持Jedis 客户端操作;
     *
     */
    @Bean
    public RedisTemplate<String,Object> redisTemplate(LettuceConnectionFactory factory){
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);

        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);

        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        //在使用注解@Bean返回RedisTemplate时,同时配置hashkey与hashvalue的序列化方式。
        //key序列化方式采用String
        template.setKeySerializer(stringRedisSerializer);
        //value序列化方式采用JACKSON
        template.setValueSerializer(jackson2JsonRedisSerializer);
        //hash的key序列化方式采用String
        template.setHashKeySerializer(stringRedisSerializer);
        //hash的value序列化方式采用JACKSON
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }
}

创建接口

package com.yang.service;

import com.yang.pojo.User;

/**
 * Description:
 * date: 2020/7/4 22:28
 *
 * @author Crille-g
 * @version 1.0
 */
public interface UserService {
    public String getString(String key);
    public User selectById(String id);
    public void expireStr(String key,String value);
}

实现接口

package com.yang.service.impl;

import com.yang.pojo.User;
import com.yang.service.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * Description:
 * date: 2020/7/4 22:29
 *
 * @author Crille-g
 * @version 1.0
 */
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

    private Logger log=LoggerFactory.getLogger(UserServiceImpl.class);

    /**
     *测试String类型
     */
    @Override
    public String getString(String key) {
//        System.out.println(redisTemplate);
//        log.info("redistemplate测试");
        if (redisTemplate.hasKey(key)){//判断key是否存在
            log.info("redis中查询");
            return (String) redisTemplate.opsForValue().get(key);


        }else{
            String val="lettuce";
            log.info("mysql中查询");
            redisTemplate.opsForValue().set(key,val);
            log.info("存入redis中");
            return val;
        }

    }
    /**
     *测试String类型
     * 用户输入数据时,给key设置一个有效期
     */
    public void expireStr(String key,String value){
        redisTemplate.opsForValue().set(key,value);
        redisTemplate.expire(key,1, TimeUnit.HOURS);
    }

    /**
     * 测试hash类型
     * @param id
     * @return
     */

    @Override
    public User selectById(String id) {
//        redisTemplate.hasKey(key)  判断整个key是否存在;
        // user:id user:1 user:2
        if (redisTemplate.opsForHash().hasKey("user",id)){
            log.info("redis中查询");
            return (User)redisTemplate.opsForHash().get("user", id);
        }else{
             log.info("查询mysql");
             User user=new User();
             user.setAge(20);
             user.setName("网二");
             user.setId(id);
             /*
             @param h 用户实体
             @param hk 用户主键 id
             @param h 整个对象
              */
             redisTemplate.opsForHash().put("user",id,user);
             return user;
        }

    }
}

测试代码

package com.yang;

import com.yang.pojo.User;
import com.yang.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import javax.xml.ws.soap.Addressing;

@SpringBootTest
class BootLettuceApplicationTests {
    @Autowired
    private UserService userService;

    @Test
    void contextLoads() {
        userService.getString("aaaa");
    }

    @Test
    void t1() {
        System.out.println(userService.getString("redisTemplate")
        );
    }
    @Test
    void t2(){
        userService.expireStr("test","测试");
        System.out.println("操作成功");
    }
    @Test
    void t3(){
        User user=userService.selectById("1000");
        System.out.println("查询的结果"+user);
    }
}

代码出现的问题

问题1:代码在传递数据时出现了很多相同的字符串。//把重复使用的提取出来
//方案一:声明一个工具类,直接调用常量
public interface KeyNameUtil {
    public static  final String USER="user";

}
public User selectById(String id) {
//        redisTemplate.hasKey(key)  判断整个key是否存在;
        // user:id user:1 user:2
        if (redisTemplate.opsForHash().hasKey(KeyNameUtil.USER,id)){
            log.info("redis中查询");
            return (User)redisTemplate.opsForHash().get(KeyNameUtil.USER, id);
        }else{
             log.info("查询mysql");
             User user=new User();
             user.setAge(20);
             user.setName("网二");
             user.setId(id);
             /*
             @param h 用户实体
             @param hk 用户主键 id
             @param h 整个对象
              */
             redisTemplate.opsForHash().put(KeyNameUtil.USER,id,user);
             return user;
        }

    }
//方案二:在实体类中,声明方法获取常量
public class User implements Serializable {
    private String name;
    private String id;
    private Integer age;

    public static String getKeyName(){
        return "user";
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", id='" + id + '\'' +
                ", age=" + age +
                '}';
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}
public User selectById(String id) {
//        redisTemplate.hasKey(key)  判断整个key是否存在;
        // user:id user:1 user:2
        if (redisTemplate.opsForHash().hasKey(User.getKeyName(),id)){
            log.info("redis中查询");
            return (User)redisTemplate.opsForHash().get(User.getKeyName(), id);
        }else{
             log.info("查询mysql");
             User user=new User();
             user.setAge(20);
             user.setName("网二");
             user.setId(id);
             /*
             @param h 用户实体
             @param hk 用户主键 id
             @param h 整个对象
              */
             redisTemplate.opsForHash().put(User.getKeyName(),id,user);
             return user;
        }

    }
问题2:强制类型转换问题
问题3:RedisTemplate.opsFor**()写的很长一串
//解决方案:

@Resource(name = "redisTemplate")
private ValueOperations<String,String> string ;//相当于RedisTemplate.opsForValue();
@Resource(name = "redisTemplate")
private HashOperations<String,String,User> hash;//k:user; hk:id; hv:Object
//return (String) redisTemplate.opsForValue().get(key);
return string.get(key);
// redisTemplate.opsForValue().set(key,val);
string.set(key,val);
-----------------------------------
//return (User)redisTemplate.opsForHash().get(User.getKeyName(), id);
  return hash.get(User.getKeyName(),id);
// redisTemplate.opsForHash().put(User.getKeyName(),id,user);
   hash.put(User.getKeyName(),id,user);
对于Spring Boot整合Lettuce,你可以按照以下步骤进行操作: 1. 首先,在你的Spring Boot项目的pom.xml文件中添加Lettuce的依赖项。例如,你可以添加以下代码到<dependencies>标签中: ```xml <dependency> <groupId>io.lettuce</groupId> <artifactId>lettuce-core</artifactId> <version>VERSION</version> </dependency> ``` 确保将`VERSION`替换为你希望使用的Lettuce版本。 2. 接下来,你需要配置Lettuce连接到Redis服务器。在Spring Boot中,你可以在`application.properties`或`application.yml`文件中进行配置。例如,如果你使用`application.properties`文件,可以添加以下配置: ```properties spring.redis.host=your_redis_host spring.redis.port=your_redis_port spring.redis.password=your_redis_password (如果有密码的话) ``` 确保将`your_redis_host`、`your_redis_port`和`your_redis_password`替换为你的Redis服务器的实际信息。 3. 在你的Spring Boot应用程序中,你可以使用`LettuceConnectionFactory`来创建Redis连接工厂,并将其注入到需要使用Redis的组件中。例如,你可以创建一个配置类来完成这个任务,如下所示: ```java @Configuration public class RedisConfig { @Value("${spring.redis.host}") private String host; @Value("${spring.redis.port}") private int port; @Value("${spring.redis.password}") private String password; @Bean public LettuceConnectionFactory lettuceConnectionFactory() { RedisStandaloneConfiguration config = new RedisStandaloneConfiguration(host, port); config.setPassword(RedisPassword.of(password)); return new LettuceConnectionFactory(config); } @Bean public RedisTemplate<String, Object> redisTemplate() { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(lettuceConnectionFactory()); return template; } } ``` 在上面的配置中,我们使用`RedisStandaloneConfiguration`来配置Redis连接,并使用`LettuceConnectionFactory`来创建连接工厂。然后,我们使用`RedisTemplate`来操作Redis。 4. 现在,你可以在你的应用程序中注入`RedisTemplate`,并使用它来进行Redis操作。例如,你可以在一个服务类中注入`RedisTemplate`,并使用它来执行一些基本的Redis操作,如下所示: ```java @Service public class RedisService { private final RedisTemplate<String, Object> redisTemplate; public RedisService(RedisTemplate<String, Object> redisTemplate) { this.redisTemplate = redisTemplate; } public void setValue(String key, String value) { redisTemplate.opsForValue().set(key, value); } public String getValue(String key) { return (String) redisTemplate.opsForValue().get(key); } } ``` 在上面的示例中,我们使用`opsForValue()`方法来获取一个用于操作字符串的操作对象,并使用它来设置和获取值。 这就是整合Spring Boot和Lettuce的基本步骤。你可以根据自己的需求进一步扩展和使用Lettuce的其他功能。希望对你有所帮助!如果还有其他问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值