Spring Data R2DBC 入门

2020-05-24  本文已影响0人  稻草鸟人

1、介绍

R2DBC(Reactive Relational Database Connectivity)是在2018年Spring One Platform大会被提出来的,它旨在使用完全无阻塞驱动程序创建数据库链接,为SQL数据库创建响应式API。为了探索R2DBC我们将创建一个简单的WebFlux应用实现目标

2、项目配置

我们通过Spring Initializr创建一个新的项目,如下图所示选择我们需要的依赖。确保Spring Boot的版本大于等于2.3.0。因为在此版本之后才开始支持MYSQL的响应式驱动

project-setup.png

Maven依赖如下:

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-r2dbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>
        <dependency>
            <groupId>org.liquibase</groupId>
            <artifactId>liquibase-core</artifactId>
        </dependency>

        <dependency>
            <groupId>dev.miku</groupId>
            <artifactId>r2dbc-mysql</artifactId>
            <scope>runtime</scope>
        </dependency>

3、脚本准备

create table test.users
(
    id         bigint auto_increment,
    first_name varchar(50) null,
    last_name  varchar(50) null,
    created_at datetime    null,
    updated_at datetime    null,
    constraint users_id_uindex
        unique (id)
);

alter table test.users
    add primary key (id);

4、应用代码

4.1 实体对象

注意这里用的日期类型是java.time.LocalDateTime,默认不能使用java.sql.Date、java.util.Date、java.sql.Timestamp类型,否则会提示错误。默认支持的类型转换参考org.springframework.data.r2dbc.convert.R2dbcConverters类。

@Table(value = "users")
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
public class User {

    @Id
    private Long id;

    @Column(value = "first_name")
    private String firstName;

    @Column(value = "last_name")
    private String lastName;

    @Column(value = "created_at")
    private LocalDateTime createdAt;

    @Column(value = "updated_at")
    private LocalDateTime updatedAt;

}

4.2 控制层代码

/**
 * 支持增加、修改、删除、查询
 * @date 2020-05-24
 * @author 稻草鸟人
 */
@RestController
@RequestMapping("/v1")
public class UserController {

    private final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

    @GetMapping(path = "/users/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseStatus(code = HttpStatus.OK)
    public Mono<User> getUser(@PathVariable("id") Long id) {
        Mono<User> userMono = userService.find(id);
        return userMono;
    }

    @PutMapping("/users/{id}")
    public Mono<User> update(@PathVariable("id") Long id, @RequestBody User user) {
        return this.userService.find(id)
                .map(u -> {
                    u.setFirstName(user.getFirstName());
                    u.setLastName(user.getLastName());
                    return u;
                })
                .flatMap(u -> save(u));
    }

    @DeleteMapping("/users/{id}")
    public Mono<Void> delete(@PathVariable("id") Long id) {
        return userService.delete(id);
    }


    @PostMapping("/users")
    public Mono<User> save(@RequestBody User user) {
        return userService.save(user);
    }

其他代码不再贴了,具体参考下面的源码部分

5、简单测试

r2dbc-update-user.png r2dbc-create-user.png

目前只是简单的测试,后面我们做一次简单的压测,比较下非阻塞接口和同步接口的性能差异吧!

6、源码

https://github.com/cattles/fucking-great-r2dbc

上一篇下一篇

猜你喜欢

热点阅读