这是我参与8月更文挑战的第10天,活动详情查看:8月更文挑战
Spring WebFlux提供了注解式和函数式的使用方式。注解式类似于Spring MVC使用注解开发接口,函数式使用RouterFunction (路由函数)和HandlerFunction (处理函数)开发接口。本文演示注解式的开发方式。
示例
-
新建项目
-
添加依赖
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>
- 编写yml配置文件
Spring Data R2DBC和Spring 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
- 编写创建实体类
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异常
- 创建实体类的
Repository创建接口,继承R2dbcRepository接口。R2dbcRepository接口提供了响应式的增删改查方法类似于JPA中的JpaRepository接口。
public interface UserRepository extends R2dbcRepository<User, Integer> {
}
R2dbcRepository提供了增删改查、分页查询、命名查询、jpql等功能,继承图如下所示:
- 编写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("删除成功");
}
}
结果
- 新增User
新增不传name字段时,效验未通过
-
查询所有User
-
根据id查询User
-
修改User
-
删除User