1 Jedis的基本使用

1.1 Maven依赖:

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

1.2 基本使用

public class JedisTest {  
    private Jedis jedis;  
    @BeforeEach  
    void before() {  
        // 1. 建立连接  
        jedis = new Jedis("124.71.200.50", 6379);  
        // 2. 设置密码  
        jedis.auth("adminpassword");  
        // 3. 选择库  
        jedis.select(0);  
    }  
    @Test // 字符类型
    void testString(){  
        // 存入数据  
        String result = jedis.set("name", "qingyang");  
        System.out.println("result:" + result);  
        // 读取数据  
        String readResult = jedis.get("name");  
        System.out.println("readResult:" + readResult);  
    }  
    @Test // Hash类型
    void testHash(){  
        // 存入数据  
        jedis.hset("user:1", "name", "qingyang");  
        jedis.hset("user:2", "name", "lazyking");  
        jedis.hset("user:2", "age", "18");  
        // 读取数据  
        String user1Name = jedis.hget("user:1", "name");  
        System.out.println(user1Name);  
        Map<String, String> user2All = jedis.hgetAll("user:2");  
        System.out.println(user2All);  
    }  
    @AfterEach  
    void after(){  
        // 关闭连接  
        if (jedis != null) {  
            jedis.close();  
        }  
    }  
  
}

1.3 连接池

创建工厂类:

public class JedisPoolFactory {  
    private static final JedisPool jedisPool;  
  
    static {  
        // 配置连接池  
        JedisPoolConfig poolConfig = new JedisPoolConfig();  
        poolConfig.setMaxTotal(8);  
        poolConfig.setMaxIdle(8);  
        poolConfig.setMinIdle(0);  
        poolConfig.setMaxWait(Duration.of(1000, ChronoUnit.SECONDS));  
        // 创建连接池对象  
        jedisPool = new JedisPool(poolConfig, "124.71.200.50", 6379, 1000, "adminpassword");  
    }  
  
    public static Jedis getJedis(){  
        return jedisPool.getResource();  
    }  
}

使用:

public class main {  
    public static void main(String[] args) {  
        // 1. 获取连接  
        Jedis jedis = JedisPoolFactory.getJedis();  
        // 2. 存取数据  
        // 存入数据  
        String result = jedis.set("name", "qingyang");  
        System.out.println("result:" + result);  
        // 读取数据  
        String readResult = jedis.get("name");  
        System.out.println("readResult:" + readResult);  
    }  
}

2 Springboot整合redis

2.1 Maven依赖

<!-- 必要的依赖  -->
<dependency>  
    <groupId>org.springframework.boot</groupId>  
    <artifactId>spring-boot-starter-test</artifactId>  
    <scope>test</scope>  
</dependency>  
<dependency>  
    <groupId>org.apache.commons</groupId>  
    <artifactId>commons-pool2</artifactId>  
</dependency>
<!-- 使用到的JSON工具 -->
<dependency>  
    <groupId>com.fasterxml.jackson.core</groupId>  
    <artifactId>jackson-databind</artifactId>  
</dependency>

2.2 基本使用:

@SpringBootTest  
public class RedisTemplateTest {  
    @Autowired // 注入RedisTemplate对象
    private RedisTemplate<String, Object> redisTemplate;  
  
    @Test  
    void testString() {  
        ValueOperations valueOps = redisTemplate.opsForValue();  
        valueOps.set("name", "lazyking");  
  
        Object name = valueOps.get("name");  
        System.out.println(name);  
    }  
  
    @Test  
    void testObject(){  
        ValueOperations<String, Object> valueOps = redisTemplate.opsForValue();  
        valueOps.set("user:100", new User("qingyang", 18, "男"));  
  
        User user = (User) valueOps.get("user:100");  
        System.out.println(user);  
    }  
}

存在的问题:

由于RedisTemplate默认使用的是JDK序列化,存储的数据在redis中会显示为二进制格式:

-- 使用redis-cli查看
127.0.0.1:6379> keys *
 1) "\xac\xed\x00\x05t\x00\x04name"

2.3 指定序列化的方式

创建config类:RedisTemplateConfig

@Configuration  
public class RedisConfig {  
    @Bean  
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory){  
        // 创建RedisTemplate对象  
        RedisTemplate<String, Object> template = new RedisTemplate<>();  
        // 设置连接工厂  
        template.setConnectionFactory(factory);  
        // 创建JSON序列化工具  
        GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();  
        // 设置key的序列化  
        template.setKeySerializer(RedisSerializer.string());  
        template.setHashKeySerializer(RedisSerializer.string());  
        // 设置value的序列化  
        template.setValueSerializer(jsonRedisSerializer);  
        template.setHashKeySerializer(jsonRedisSerializer);  
        // 返回  
        return template;  
    }  
}

存在问题:

在使用GenericJackson2JsonRedisSerializer进行序列化时,存储在Redis中的数据会自动添加一个@class属性。这个属性用于存储序列化对象的完全限定类名,以便在反序列化时能够正确地还原为相应的对象类型。

例如,当你存储一个User对象时,存储在Redis中的JSON数据可能如下所示:

{  
  "@class": "site.lazyking.redistemplateexperience.entity.User",  
  "name": "qingyang",  
  "age": 18,  
  "sex": "男"  
}

这个@class属性确保了对象在反序列化时能够正确地还原为User对象。然而,这也意味着存储在Redis中的数据会因为额外的元数据而稍微变大。

2.4 使用StringRedisTemplate

可以使用StringRedisTemplate来解决@Class属性的问题,同时也带来了一个麻烦,我们不得不手动进行序列化和反序列化。

@SpringBootTest  
public class StringRedisTemplateTest {  
  
    @Autowired  
    private StringRedisTemplate template;  
  
    @Test  
    void testUser() throws JsonProcessingException {  
        // 创建对象  
        User user = new User("qingyang", 18, "man");  
        // 手动序列化  
        ObjectMapper mapper = new ObjectMapper();  
        String jsonUser = mapper.writeValueAsString(user);  
        // 导入数据  
        template.opsForValue().set("user:100", jsonUser);  
        // 读取数据  
        jsonUser = template.opsForValue().get("user:100");  
        // 手动反序列化  
        user = mapper.readValue(jsonUser, User.class);  
        System.out.println("user:" + user);  
    }  
  
}