Spring WebFlux之增删改查 (注解式)

1,214 阅读2分钟

这是我参与8月更文挑战的第10天,活动详情查看:8月更文挑战


Spring WebFlux提供了注解式函数式的使用方式。注解式类似于Spring MVC使用注解开发接口,函数式使用RouterFunction (路由函数)HandlerFunction (处理函数)开发接口。本文演示注解式的开发方式。

示例

  1. 新建项目 image.png

  2. 添加依赖 r2dbc-mysql响应式的MySQL连接驱动Spring Data R2DBC需要r2dbc-mysql配合工作。引入spring-boot-starter-validation依赖主要是为了像在Spring MVC一样使用注解进行参数效验。

<!-- 响应式的MySQL驱动-->
<dependency>
    <groupId>dev.miku</groupId>
    <artifactId>r2dbc-mysql</artifactId>
</dependency>

<!-- Spring参数效验-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>
  1. 编写yml配置文件 Spring Data R2DBCSpring Data JPA一样支持Repository模式。需要注意的是Spring Data R2DBC的url使用r2dbc开头而不是jdbc
server:
  port: 8099
spring:
  data:
    r2dbc:
      repositories:
        enabled: true  # 开启Repository模式

  r2dbc:
    url: r2dbc:mysql://**********:****/user?useUnicode=true&characterEncoding=UTF-8&useSSL=false
    username: ****
    password: ****
    pool:
      enabled: true
      max-size: 10
      initial-size: 10
      validation-query: select 1
  
  1. 编写创建实体类 Spring WebFlux支持使用spring validation进行参数效验。如实体类中的name字段加上了不能为空的效验注解
@Data
@Table(value = "user")
public class User {

    @Id
    private Integer id;

    // NotBlank:效验注解
    @NotBlank(message = "name为空")
    private String name;
    
    // Java 8 新时间类型
    private LocalDate birthday;

    private String sex;
    
}

时间类型不能使用Date,不然会出现Cannot encode value of type 'class java.util.Date异常

  1. 创建实体类的Repository 创建接口,继承R2dbcRepository接口。R2dbcRepository接口提供了响应式的增删改查方法类似于JPA中的JpaRepository接口。
public interface UserRepository extends R2dbcRepository<User, Integer> {
}

R2dbcRepository提供了增删改查、分页查询、命名查询、jpql等功能,继承图如下所示:

image.png

  1. 编写Controller 创建Controller编写增删改查接口,这里功能比较简单就不写service了。Spring WebFlux标识请求接口的注解有@RequestMapping@GetMapping@PostMapping@PutMapping@DeleteMapping@PatchMapping。同时支持如下注解功能同Spring MVC
  • @PathVariable
  • @MatrixVariable
  • @RequestParam
  • @RequestHeader
  • @CookieValue
  • @RequestBody
  • @RequestPart
  • @ModelAttribute
  • @SessionAttribute
  • @RequestAttribute
@RestController
public class UserController {

    @Resource
    private UserRepository userRepository;

    // 使用@Validated注解激活参数效验
    @PostMapping("users")
    public Mono<Integer> createUser(@RequestBody @Validated User user){

        return userRepository.save(user).map(User::getId);
    }

    @GetMapping("users")
    public Flux<User> getUsers(){

        return userRepository.findAll();
    }

    @GetMapping("users/{id}")
    public Mono<User> getUserById(@PathVariable("id") Integer id){

        return userRepository.findById(id);
    }

    @PutMapping("users")
    public Mono<String> updateUser(@RequestBody User user){

        userRepository.save(user);
        return Mono.just("修改成功");
    }

    @DeleteMapping("users/{id}")
    public Mono<String> delUser(@PathVariable("id") Integer id){

        userRepository.deleteById(id);
        return Mono.just("删除成功");
    }

}

结果

  1. 新增User image.png

新增不传name字段时,效验未通过 image.png

  1. 查询所有User image.png

  2. 根据id查询User image.png

  3. 修改User image.png

  4. 删除User image.png