第二节 String典型场景

一、心法

        可以从Redis的String类型的数据结构来考虑其实际业务场景。重点需要记住的是,String类型它是一个变量对应一个值,说白了,就是一对一的场景。这种场景比较多,比如用于缓存当前登陆人的用户信息,缓存某篇文章的访问量。我自己的公司现在是做教育行业的,那么String类型完全可以用于缓存当前学生的身份信息,学生某门课的考试成绩,学生的参与某个活动的次数等等。牢牢记住,Redis的String类型用于"一对一"场景。

二、快速引入Redis

         SpringBoot中快速集成Redis的三个步骤。导入依赖,增加配置文件,增加配置代码

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
spring
  redis:
    # Redis 数据库索引(默认为 0)
    database: 0
    # Redis 服务器地址
    host: localhost
    # Redis 服务器连接端口
    port: 6379
    password: 
    timeout: 10s
    #数据连接池等配置,可参考其它网上的教程
package com.tyzhou.database;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;

/**
 * @author zhoutianyu
 * @date 2020/2/8
 * @time 17:11
 */
@Configuration
public class RedisConfig {

    @Bean
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory) {
        //操作String类型的RedisTemplate
        StringRedisTemplate redisTemplate = new StringRedisTemplate();
        redisTemplate.setConnectionFactory(factory);

        return redisTemplate;
    }

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(factory);
        //指定序列化策略
        redisTemplate.setKeySerializer(RedisSerializer.string());
        redisTemplate.setHashKeySerializer(RedisSerializer.string());
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());

        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }
}

二、String类型的应用

        Redis毕竟是一个缓存系统,最最典型的应用就是存放Java实体对象,例如商品对象、用户对象。

        毋庸置疑的,我们先把一个对象插入到Redis缓存中,然后再去Redis缓存中取出来。

        好,现有一个User对象。注意要在User对象上加入@ToString注解,并实现序列化接口。

package com.tyzhou.redis;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import java.io.Serializable;

@Data
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class User implements Serializable {
    private Long id;
    private String username;
    private String password;
}

          Redis操作工具,先写一个非常粗劣的工具类。


@Service
public class StringRedisServiceImpl implements StringRedisService {
    private static final Logger LOGGER = LoggerFactory.getLogger(StringRedisServiceImpl.class);

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public Boolean exists(String key) {
        //todo:key can be null?
        return stringRedisTemplate.hasKey(key);
    }

    @Override
    public void set(String key, String value) {
        stringRedisTemplate.opsForValue().set(key, value);
    }

    @Override
    public String get(String key) {
        return stringRedisTemplate.opsForValue().get(key);
    }
}

         核心业务。先把存放到数据库中的User,接着放到Redis缓存里。这样下次查询的时候,就能先从缓存中取。

         如果缓存中没有的话,那么就再从数据库中取。通常为了代码的健壮性,需要提供一个判断key是否存在的接口。

         我这里主要遇到的坑就是对象与JSON互转。ObjectMapper是FastJson提供的工具类。

先把User对象弄成JSON格式。

把数据以JSON格式存放

String json = objectMapper.writeValueAsString(userFromDB)

stringRedisService.set(userFromDB.getId().toString(),json );

从Redis中读取JSON,要求实体必须提供@ToString注解

String json = stringRedisService.get(userFromDB.getId().toString());

User user = objectMapper.readValue(json, User.class);

import com.fasterxml.jackson.databind.ObjectMapper;

@Service
public class UserItemService ...

    @Autowired
    private ObjectMapper objectMapper;

    public void addUser() throws Exception {
        //这里操作数据库成功,返回此User
        User userFromDB = insert();
        //将其放入缓存
        stringRedisService.set(userFromDB.getId().toString(),
                          objectMapper.writeValueAsString(userFromDB));
    }

    public User getUser() throws Exception {
        User userFromDB = insert();
        String key = userFromDB.getId().toString();

        //查询的时候,先查询Redis缓存,客户端肯定会传一个ID过来
        if (stringRedisService.exists(key)) {
            LOGGER.info("从Redis缓存中查询User");
            String result = stringRedisService.get(key);
            return objectMapper.readValue(result, User.class);

        } else {
            LOGGER.info("从数据库中查询User");
            return userFromDB;
        }
    }
}

         最终效果。

          Redis的set与get,实在是太过简单,我想哪个公司都会有。网上的Redis工具类天花乱坠。

          估计以后我看到这篇文章的时候,也只会花了不到30秒就扫描完。

    JSONObject.parseObject(redisValue, SystemStepDO.class);
    redisTemplate.opsForValue().set(key, value);
    return redisTemplate.opsForValue().get(key);
    redisTemplate.delete(key);

阅读更多 

        跟着大宇学Redis--------目录帖

posted @ 2022-07-17 12:14  小大宇  阅读(21)  评论(0编辑  收藏  举报