目录
前言
1.简单集成MongoDB
2. yml配置
3.创建用户实体类
4.创建用户CRUD数据访问接口类
5.Controller层
6.postman测试访问
7.代码附在本博文绑定资源
前言
MongoDB广泛应用于非关系型数据库的存储,其主要存储的数据类型有字符串,整数、浮点数,日期、数组和嵌套文档等,这些数据结构,使得它在存储半结构化和非结构化数据占有一定的优势。
MongoDB的特点:高性能、可扩展性、高可用性。
高性能:MongoDB使用内存映射技术讲数据存储在内存中,通过预读和缓存来提高数据访问速度,支持索引查询优化,加快查询速度。
可扩展性:MongDB支持水平扩展和垂直扩展,可通过增加新节点来提高吞吐量和存储容量,通过自身分片技术,可以将数据分布在多个节点,实现高可用和负载均衡。
高可用性:MongoDB支出自动分片,在集群中,可设置一个主副本和多个副本,当主副本发生故障时,可以自主选举新的主副本,保证系统的持续可用。
1.简单集成MongoDB
1.1 引入相关依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
</dependency>
2. yml配置
spring:
data:
mongodb:
uri: mongodb://127.0.0.1:27017/webflux
3.创建用户实体类
package com.example.spring.mono.entity;
import lombok.Data;
import org.hibernate.validator.constraints.Range;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import javax.validation.constraints.NotBlank;
/**
* @program: webflux-demo
* @description: User实体类
* @author: 01
* @create: 2018-10-04 20:25
**/
@Data
@Document(collection = "user")
public class User {
@Id
private String id;
@NotBlank(message = "用户名称不可以为空")
private String name;
@Range(min = 10, max = 100, message = "用户年龄需在10-100岁之间")
private int age;
}
4.创建用户CRUD数据访问接口类
package com.example.spring.mono.repository;
import com.example.spring.mono.entity.User;
import org.springframework.data.mongodb.repository.Query;
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
import org.springframework.stereotype.Repository;
import reactor.core.publisher.Flux;
/**
* @program: webflux-demo
* @description: user dao层接口
* @author: 01
* @create: 2018-10-04 20:27
**/
@Repository
public interface UserRepository extends ReactiveMongoRepository<User, String> {
}
5.Controller层
package com.example.spring.mono.controller;
import com.example.spring.mono.entity.User;
import com.example.spring.mono.repository.UserRepository;
import com.example.spring.mono.utils.CheckUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import javax.validation.Valid;
/**
* @program: webflux-demo
* @description: User 接口
* @author: 01
* @create: 2018-10-04 20:29
**/
@RestController
@RequestMapping("/user")
public class UserController {
private final UserRepository userRepository;
@Autowired
public UserController(UserRepository userRepository) {
this.userRepository = userRepository;
}
/**
* 以数组形式一次返回全部数据
*/
@GetMapping(value = "/get_all")
public Flux<User> getAll() {
return userRepository.findAll();
}
/**
* 以SSE形式多次返回数据
*/
@GetMapping(value = "/stream/all", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<User> streamGetAll() {
return userRepository.findAll();
}
/**
* 添加用户
*
* @param user user
* @return 新增的用户数据
*/
@PostMapping("/save")
public Mono<User> createUser(@Valid @RequestBody User user) {
// 新增和修改都是save,有id是修改,无id则是新增
user.setId(null);
// 检查用户名是否符合规则
CheckUtil.checkName(user.getName());
return userRepository.save(user);
}
/**
* 根据id删除用户
*
* @param id id
* @return 用户存在返回200,不存在则返回404
*/
@DeleteMapping("/del/{id}")
public Mono<ResponseEntity<Void>> deleteUser(@PathVariable("id") String id) {
// deleteById没有返回值,不能判断数据是否存在,所以一般来说实现删除逻辑时不能直接使用
// userRepository.deleteById(id);
// 当你要操作数据,并返回一个Mono这个时候使用flatMap。如果不操作数据,只是转换数据,并返回一个Mono时使用map
return userRepository.findById(id).flatMap(user -> userRepository.delete(user)
// 用户存在,删除成功
.then(Mono.just(new ResponseEntity<Void>(HttpStatus.OK))))
// 用户不存在,删除失败
.defaultIfEmpty(new ResponseEntity<>(HttpStatus.NOT_FOUND));
}
/**
* 修改用户数据
*
* @param id id
* @param user user
* @return 用户数据存在时,返回200和修改后的数据,不存在则返回404
*/
@PutMapping("/update/{id}")
public Mono<ResponseEntity<User>> updateUser(@PathVariable("id") String id,
@Valid @RequestBody User user) {
CheckUtil.checkName(user.getName());
return userRepository.findById(id)
// flatMap操作数据
.flatMap(u -> {
BeanUtils.copyProperties(user, u);
u.setId(id);
return userRepository.save(u);
})
// map转换数据,用户数据存在,修改成功
.map(u -> new ResponseEntity<>(u, HttpStatus.OK))
// 用户数据不存在,修改失败
.defaultIfEmpty(new ResponseEntity<>(HttpStatus.NOT_FOUND));
}
/**
* 根据id查找用户
*
* @param id id
* @return 用户存在返回200和用户信息,不存在则返回404
*/
@GetMapping("/find/{id}")
public Mono<ResponseEntity<User>> findUserById(@PathVariable("id") String id) {
return userRepository.findById(id)
// 用户存在返回200和用户信息
.map(user -> new ResponseEntity<>(user, HttpStatus.OK))
// 不存在则返回404
.defaultIfEmpty(new ResponseEntity<>(HttpStatus.NOT_FOUND));
}
/**
* 根据年龄段查找用户数据
*
* @param start start
* @param end end
* @return 以数组形式一次返回全部用户数据
*/
@GetMapping("/age/{start}/{end}")
public Flux<User> findByAge(@PathVariable("start") int start,
@PathVariable("end") int end) {
return userRepository.findByAgeBetween(start, end);
}
/**
* 根据年龄段查找用户数据
*
* @param start start
* @param end end
* @return 以SSE形式多次返回用户数据
*/
@GetMapping(value = "/stream/age/{start}/{end}", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<User> streamFindByAge(@PathVariable("start") int start,
@PathVariable("end") int end) {
return userRepository.findByAgeBetween(start, end);
}
/**
* 查找20-45岁用户数据
*
* @return 以数组形式一次返回全部用户数据
*/
@GetMapping("/old")
public Flux<User> oldUser() {
return userRepository.oldUser();
}
/**
* 查找20-45岁用户数据
*
* @return 以SSE形式多次返回用户数据
*/
@GetMapping(value = "/stream/old", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<User> streamOldUser() {
return userRepository.oldUser();
}
}