响应式数据库无法用传统的数据库,这里用MongoDB:
1.加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
</dependency>
2.加注解
@EnableReactiveMongoRepositories
3.加配置
spring:
data:
mongodb:
uri: mongodb://localhost:27017/webflux
实体类:
@Document(collection = "user")
@Data
public class User {
@Id
private String id;
private String name;
private int age;
}
@Document(collection = "user")表示是mongodb的表,表名是user
对应mongo接口:
@Repository
public interface UserRepository extends ReactiveMongoRepository<User, String> {
}
实现:
@RestController
@RequestMapping("/user")
public class UserController {
private final UserRepository userRepository;
public UserController(UserRepository userRepository) {
this.userRepository = userRepository;
}
@GetMapping("/")
public Flux<User> getAll(){
return userRepository.findAll();
}
@GetMapping(value = "/stream" , produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<User> getStreamAll(){
return userRepository.findAll();
}
@PostMapping("/")
public Mono<User> createUser(@RequestBody User user){
return this.userRepository.save(user);
}
/**
* 根据id删除用户
* 存在返回200,不存在返回404
* @param id
* @return
*/
@DeleteMapping("/{id}")
public Mono<ResponseEntity<Void>> deleteUser(@PathVariable("id") String id){
//deleteById是没有返回值的,无法知道是否删除成功,所以不能用这个
// this.userRepository.deleteById(id)
return this.userRepository.findById(id)
//当要操作数据,并返回一个Mono,用flatMap
//如果不操作数据,只是转换数据,用map
.flatMap(user -> this.userRepository.delete(user)
.then(Mono.just(new ResponseEntity<Void>(HttpStatus.OK))))
.defaultIfEmpty(new ResponseEntity<>(HttpStatus.NOT_FOUND));
}
@PutMapping("/{id}")
public Mono<ResponseEntity<User>> updateUser(
@PathVariable("id") String id,
@RequestBody User user
){
return this.userRepository.findById(id)
//flat 操作数据
.flatMap(u -> {
u.setAge(user.getAge());
u.setName(user.getName());
return this.userRepository.save(u);
})
//map 转换数据
.map(u -> new ResponseEntity<User>(u , HttpStatus.OK))
.defaultIfEmpty(new ResponseEntity<>(HttpStatus.NOT_FOUND));
}
@GetMapping("/{id}")
public Mono<ResponseEntity<User>> findUserById(@PathVariable("id") String id){
return this.userRepository.findById(id)
.map(u -> new ResponseEntity<User>(u , HttpStatus.OK))
.defaultIfEmpty(new ResponseEntity<>(HttpStatus.NOT_FOUND));
}
}
需要注意的是在spring data jpa中,新增和修改都是save,有id是修改,没有id是新增。
还可以对参数进行校验(用hibernate),依赖:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.3.6.Final</version>
</dependency>
代码:
@Document(collection = "user")
@Data
public class User {
@Id
private String id;
@NotBlank
private String name;
@Range(min = 10 , max = 100)
private int age;
}
新增切面:
/**
* 异常处理切面
*/
@ControllerAdvice
public class CheckAdvice {
@ExceptionHandler(WebExchangeBindException.class)
public ResponseEntity handleBindException(WebExchangeBindException exception){
return new ResponseEntity<String>(toStr(exception) , HttpStatus.BAD_REQUEST);
}
private String toStr(WebExchangeBindException exception) {
return exception.getFieldErrors().stream()
.map(e -> e.getField() + ":" + e.getDefaultMessage())
.reduce("" , (s1 , s2) -> s1 + "\n" + s2);
}
}
在需要校验单的接口加注解: