SpringBoot整合Redis

狂风中的少年 提交于 2020-02-10 15:44:28

Redis

非关系型数据库的代表,基于内存进行存储,支持key-value的存储形式,底层是用C语言来编写的。

基于key-value形式的数据字典,结构非常简单,没有数据表的概念,直接用键值对的形式完成数据的管理,Redis支持5中数据类型:

  • 字符串
  • 列表
  • 集合
  • 有序集合
  • 哈希

SpringBoot整合Redis

实质是使用Spring Data Redis操作Redis

1、搭建环境,引入依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.qianyu</groupId>
    <artifactId>demo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.3.RELEASE</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>
</project>

创建实体类,注意必须实现序列化接口,否则无法存入Redis数据库

package com.qianyu.entity;

import lombok.*;

import java.io.*;
import java.util.*;

@Data
public class Student implements Serializable {
    private Integer id;
    private String name;
    private Double score;
    private Date birthday;
}

3、 创建控制器

package com.qianyu.controller;

import com.qianyu.entity.*;
import org.springframework.beans.factory.annotation.*;
import org.springframework.data.redis.core.*;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/student")
public class StudentHandler {
    @Autowired
    private RedisTemplate redisTemplate;

    @PostMapping("/")
    public String set(@RequestBody Student student) {
        redisTemplate.opsForValue().set("student", student);
        return "ok";
    }

    @GetMapping("/{key}")
    public Student get(@PathVariable String key) {
        return (Student) redisTemplate.opsForValue().get(key);
    }

    @DeleteMapping("/{key}")
    public boolean delete(@PathVariable String key) {
        Boolean res = redisTemplate.delete(key);
        return !redisTemplate.hasKey(key);
    }
}

4、创建配置文件,配置端口和Redis属性

server:
  port: 9000
spring:
  redis:
    database: 0 # 表示使用redis通统一数据库
    host: localhost
    port: 6379

5、创建启动类

package com.qianyu;

import org.springframework.boot.*;
import org.springframework.boot.autoconfigure.*;

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

测试CRUD

1、测试插入

编写http脚本

POST http://localhost:9000/student/
Content-Type: application/json

{
  "id": 1,
  "name": "Lisa",
  "birthday": "2000-05-21",
  "score": 99.5
}

运行结果如下,说明执行成功:

POST http://localhost:9000/student

HTTP/1.1 200 
Content-Type: text/plain;charset=UTF-8
Content-Length: 2
Date: Sun, 09 Feb 2020 14:11:53 GMT
Keep-Alive: timeout=60
Connection: keep-alive

ok

Response code: 200; Time: 548ms; Content length: 2 bytes

注意此时在redis-cli客户端使用get student查询的时候是查询不出来的。因为Redis在存入键值对的时候对键值对进行了序列化。使用keys *student可以查询到序列化之后的key,根据序列化之后的key可以找到刚才存进去的值

2、测试从Redis中取数据

测试脚本以及执行结果如下:

GET http://localhost:9000/student/student/

###

GET http://localhost:9000/student/student

HTTP/1.1 200 
Content-Type: application/json
Transfer-Encoding: chunked
Date: Sun, 09 Feb 2020 14:22:51 GMT
Keep-Alive: timeout=60
Connection: keep-alive

{
  "id": 1,
  "name": "Lisa",
  "score": 99.5,
  "birthday": "2000-05-21T00:00:00.000+0000"
}

Response code: 200; Time: 639ms; Content length: 77 bytes

3、测试删除

返回true,说明删除成功

DELETE http://localhost:9000/student/student/
### 
DELETE http://localhost:9000/student/student

HTTP/1.1 200 
Content-Type: application/json
Transfer-Encoding: chunked
Date: Sun, 09 Feb 2020 14:33:47 GMT
Keep-Alive: timeout=60
Connection: keep-alive

true

Response code: 200; Time: 610ms; Content length: 4 bytes

再次查询,返回对象为空

GET http://localhost:9000/student/student/
###
GET http://localhost:9000/student/student

HTTP/1.1 200 
Content-Length: 0
Date: Sun, 09 Feb 2020 14:34:43 GMT
Keep-Alive: timeout=60
Connection: keep-alive

<Response body is empty>

Response code: 200; Time: 41ms; Content length: 0 bytes

Redis五种数据类型的存取

对象、字符串

使用redisTemplate.opsForValue()方法来存取

package com.qianyu.controller;

import org.springframework.beans.factory.annotation.*;
import org.springframework.data.redis.core.*;
import org.springframework.web.bind.annotation.*;

@RestController
public class RedisHandler {
    @Autowired
    private RedisTemplate redisTemplate;

    @GetMapping("/str")
    public String str() {
        redisTemplate.opsForValue().set("str", "Hello World");
        return (String) redisTemplate.opsForValue().get("str");
    }
}

测试:

GET http://localhost:9000/str

HTTP/1.1 200 
Content-Type: text/plain;charset=UTF-8
Content-Length: 11
Date: Mon, 10 Feb 2020 03:23:43 GMT
Keep-Alive: timeout=60
Connection: keep-alive

Hello World

Response code: 200; Time: 1573ms; Content length: 11 bytes

列表

列表相当于java中的List,即可以存储重复的值,使用redisTemplate.opsForList()来进行存取

@GetMapping("/list")
public List<String> list() {
    // ListOperations<K, V> 的泛型由自己决定,决定了即集合里面存什么样的数据类型
    ListOperations<String, String> listOperations = redisTemplate.opsForList();
    // listOperations相当于一个管道,可以从左边放,也可以从右边放;同样可以从左边取出,也可以从右边取出
    listOperations.leftPush("list", "java");
    listOperations.leftPush("list", "python");
    listOperations.leftPush("list", "golang");
    // 根据下标,取出指定范围的元素,这里的区间是左右都包含
    List<String> list = listOperations.range("list", 0, 2);
    return list;
}

测试:

GET http://localhost:9000/list

HTTP/1.1 200 
Content-Type: application/json
Transfer-Encoding: chunked
Date: Mon, 10 Feb 2020 03:34:21 GMT
Keep-Alive: timeout=60
Connection: keep-alive

[
  "golang",
  "python",
  "java"
]

Response code: 200; Time: 851ms; Content length: 26 bytes

可以看出,列表取的顺序和存入的顺序相反

集合

集合相当于java中的Set类型,使用redisTemplate.opsForSet来存取

@GetMapping("/set")
public Set<String> set() {
    SetOperations<String, String> setOperations = redisTemplate.opsForSet();
    // 重复元素不会重复存入
    setOperations.add("set", "SpringBoot");
    setOperations.add("set", "SpringBoot");
    setOperations.add("set", "SpringData");
    setOperations.add("set", "SpringData");
    setOperations.add("set", "SpringCloud");
    Set<String> set = setOperations.members("set");
    return set;
}

测试脚本及运行结果:

GET http://localhost:9000/set

HTTP/1.1 200 
Content-Type: application/json
Transfer-Encoding: chunked
Date: Mon, 10 Feb 2020 03:43:17 GMT
Keep-Alive: timeout=60
Connection: keep-alive

[
  "SpringData",
  "SpringCloud",
  "SpringBoot"
]

Response code: 200; Time: 654ms; Content length: 41 bytes

有序集合

@GetMapping("/zset")
public Set<String> zset() {
    ZSetOperations<String, String> zSetOperations = redisTemplate.opsForZSet();
    // 第三个参数表示序号,Redis按照序号存储
    zSetOperations.add("zset", "Next.js", 2);
    zSetOperations.add("zset", "Nest.js", 1);
    zSetOperations.add("zset", "Nuxt.js", 3);
    Set<String> zset = zSetOperations.range("zset", 0, 2);
    return zset;
}

测试:

GET http://localhost:9000/zset

HTTP/1.1 200 
Content-Type: application/json
Transfer-Encoding: chunked
Date: Mon, 10 Feb 2020 03:50:37 GMT
Keep-Alive: timeout=60
Connection: keep-alive

[
  "Nest.js",
  "Next.js",
  "Nuxt.js"
]

Response code: 200; Time: 673ms; Content length: 31 bytes

哈希

Redis中的hash相当于将一个键值对整体当做值存入

@GetMapping("/hash")
public String hash() {
    HashOperations<String, String, String> hashOperations = redisTemplate.opsForHash();
    hashOperations.put("key", "hashKey", "value");
    String value = hashOperations.get("key", "hashKey");
    return value;
}

上面例子就相当于将以key为键,键为hashKey值为value的键值对为值,存入Redis

测试:

GET http://localhost:9000/hash

HTTP/1.1 200 
Content-Type: text/plain;charset=UTF-8
Content-Length: 5
Date: Mon, 10 Feb 2020 04:09:26 GMT
Keep-Alive: timeout=60
Connection: keep-alive

value

Response code: 200; Time: 668ms; Content length: 5 bytes
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!