分布式缓存redis,看这一篇就够了

redis是什么?

简单来说redis是一个开源的使用ANSI C语言编写的内存数据库,使用key-value的数据结构。支持数据持久化到硬盘,支持多种api语言的连接。通常当做缓存处理。

安装redis

  1. redis官网:https://redis.io 英语好的看官网,下载linux版本redis
  2. redis for windows: https://github.com/MicrosoftArchive/redis/releases ,windows版下载到本地直接安装即可使用。

windows版本下载安装完成之后,在services.msc里面能看到redis服务。

springboot集成redis

我们使用redisson框架集成,新建工程,pom中添加如下依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>
<!-- https://mvnrepository.com/artifact/org.redisson/redisson -->
<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson</artifactId>
    <version>3.15.0</version>
</dependency>

修改application.yml文件,添加redis的配置

spring:
  redisson:
    address: redis://127.0.0.1:6379 #redis的地址和端口,默认端口是6379
    password: #默认没有买卖
    database: 0 #Redis默认情况下有16个分片,这里配置具体使用的分片,默认是0
    timeout: 10000 #连接超时时间(毫秒)

添加配置类,映射yml文件中的属性

@Getter
@Setter
@Configuration
@ConfigurationProperties(prefix = "spring.redisson")//获取yml文件中以spring.redisson开头的所有数据
public class RedissonProperties {
    //映射yml文件里面的数据
    private String address;
    private String password = null;
    private int database = 0;
    private int timeout = 3000;
}

增加RedissonClient初始化类:

@Configuration
@ConditionalOnClass(RedissonClient.class)//存在RedissonClient才创建该类
@ConditionalOnProperty({"spring.redisson.address"})//存在spring.redisson.address配置才创建该类
public class RedissonConfig {

    @Resource
    private RedissonProperties properties;

    @Bean(destroyMethod = "shutdown")
    RedissonClient redissonClient(RedissonProperties properties) throws Exception {
        Config config = new Config();
        SingleServerConfig singleServerConfig = config.useSingleServer();
        singleServerConfig
                .setAddress(properties.getAddress())
                .setDatabase(properties.getDatabase())
                .setTimeout(properties.getTimeout());
        //密码不为空才设置,否则默认yml注入的空串会导致创建redisson不成功
        if(!StringUtils.isEmpty(properties.getPassword())){
            singleServerConfig.setPassword(properties.getPassword());
        }

        return Redisson.create(config);
    }
}

好了,自此,准备工作都做好了,下面就可以编码操作redis的数据了。

@RestController
@RequestMapping("demo")
public class DemoController {
    @Resource
    private RedissonClient redissonClient;

    public static String MAP_KEY = "MAP";
    public static String SET_KEY = "SET";
    public static String LIST_KEY = "LIST";

    @GetMapping("put")
    public String put(){
        RMap<String, String> map = redissonClient.getMap(MAP_KEY);
        map.put("a","hello redis");
        return "ok";
    }

    @GetMapping("get")
    public String get(){
        RMap<String, String> map = redissonClient.getMap(MAP_KEY);
        return map.get("a");
    }
}

先用postman请求http://localhost:8080/demo/put 将数据放进去,然后找一个redis的ide工具(本文用的是redis studio)查看redis中的数据

数据是放进去了,而且使用http://localhost:8080/demo/get 也能将数据拿出来,不过用redis的ide工具怎么那么不形象呢,不好看。。。那是因为你在使用redissonClient的时候没有指定序列化方式。修改代码如下:

RMap<String, String> map = redissonClient.getMap(MAP_KEY, JsonJacksonCodec.INSTANCE);

再试下看看redis studio怎么显示的:

怎么样,清晰了吧。那RMap只能放基本数据对象吗》能不能放自定义对象?建一个dto:

@Data
public class UserDto implements Serializable {
    private String username;
    private Integer age;
    private Date birthday;
    private List<String> fav;
}

新增rest方法:

@GetMapping("put2")
public String put2(){
    RMap<String, UserDto> map = redissonClient.getMap(MAP_KEY, JsonJacksonCodec.INSTANCE);
    UserDto userDto = new UserDto();
    userDto.setUsername("张三6");
    userDto.setAge(18);
    userDto.setBirthday(new Date());
    userDto.setFav(Arrays.asList("apple","pear"));
    map.put("userDto",userDto);
    return "ok";
}

@GetMapping("get2")
public UserDto get2() throws InterruptedException {
    RMap<String, UserDto> map = redissonClient.getMap(MAP_KEY, JsonJacksonCodec.INSTANCE);
    UserDto userDto = map.get("userDto");
    return userDto;
}

按套路出牌,自己postman请求,然后看redis studio的数据:

怎么样,舒服了吧,对象都被你存进去了,而且还能从redis里面拿出来自己转换成UserDto对象!!!

好了,以上是RMap对象,下面的list和set我就不细解说了,直接上代码。

@GetMapping("put3")
public String put3(){
    RSet<Long> set = redissonClient.getSet(SET_KEY, JsonJacksonCodec.INSTANCE);
    set.add(System.currentTimeMillis());
    return "ok";
}

@GetMapping("get3")
public String get3() throws InterruptedException {
    RSet<Long> set = redissonClient.getSet(SET_KEY, JsonJacksonCodec.INSTANCE);
    Iterator<Long> iterator = set.iterator();
    String result = "";
    while (iterator.hasNext()){
        result +=","+iterator.next();
    }
    return result;
}

@GetMapping("put4")
public String put4(){
    RList<Long> list = redissonClient.getList(LIST_KEY, JsonJacksonCodec.INSTANCE);
    list.add(1L);
    return "ok";
}

@GetMapping("get4")
public String get4() throws InterruptedException {
    RList<Long> list = redissonClient.getList(LIST_KEY, JsonJacksonCodec.INSTANCE);
    String result="";
    for (Long aLong : list) {
        result+=aLong;
    }
    return result;
}

每次都要写JsonJacksonCodec.INSTANCE这个玩意很烦,算了,默认了吧。默认使用JsonJacksonCodec.INSTANCE序列化。那我们修改下config好了。

@Bean(destroyMethod = "shutdown")
RedissonClient redissonClient(RedissonProperties properties) throws Exception {
    Config config = new Config();
    SingleServerConfig singleServerConfig = config.useSingleServer();
    singleServerConfig
            .setAddress(properties.getAddress())
            .setDatabase(properties.getDatabase())
            .setTimeout(properties.getTimeout());
    //密码不为空才设置,否则默认yml注入的空串会导致创建redisson不成功
    if(!StringUtils.isEmpty(properties.getPassword())){
        singleServerConfig.setPassword(properties.getPassword());
    }
    //指定默认序列化
    Codec codec=(Codec) ClassUtils.forName("org.redisson.codec.JsonJacksonCodec", ClassUtils.getDefaultClassLoader()).newInstance();
    config.setCodec(codec);
    return Redisson.create(config);
}

下面来一个不指定序列化的调用redis试试:


@GetMapping("test")
public String test(){
    RMap<String, UserDto> map = redissonClient.getMap("MAP_KEY");
    UserDto userDto = new UserDto();
    userDto.setUsername("张三6d");
    userDto.setAge(18);
    userDto.setBirthday(new Date());
    userDto.setFav(Arrays.asList("apple","pear"));
    map.put("userDto",userDto);
    return "ok";
}

还乱码吗?不乱码了吧。

redis的用处远不至于此,还可以设置缓存的数据有效期,多长时间内有效,并且可以监听创建、修改、销毁数据事件,另外还有队列、发布订阅等等待大伙探索。

总结一句,redis当缓存很好用,但是持久化数据库就算了,他天生不是干那个的!

更多java原创阅读:https://javawu.com

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值