diff --git a/lab-27/lab-27-webflux-mongodb/pom.xml b/lab-27/lab-27-webflux-mongodb/pom.xml
new file mode 100644
index 00000000..5631759c
--- /dev/null
+++ b/lab-27/lab-27-webflux-mongodb/pom.xml
@@ -0,0 +1,38 @@
+
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.2.1.RELEASE
+
+
+ 4.0.0
+
+ lab-27-webflux-mongodb
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-webflux
+ 2.2.1.RELEASE
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-mongodb-reactive
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
diff --git a/lab-27/lab-27-webflux-mongodb/src/main/java/cn/iocoder/springboot/lab27/springwebflux/Application.java b/lab-27/lab-27-webflux-mongodb/src/main/java/cn/iocoder/springboot/lab27/springwebflux/Application.java
new file mode 100644
index 00000000..4f207dfc
--- /dev/null
+++ b/lab-27/lab-27-webflux-mongodb/src/main/java/cn/iocoder/springboot/lab27/springwebflux/Application.java
@@ -0,0 +1,13 @@
+package cn.iocoder.springboot.lab27.springwebflux;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class Application {
+
+ public static void main(String[] args) {
+ SpringApplication.run(Application.class, args);
+ }
+
+}
diff --git a/lab-27/lab-27-webflux-mongodb/src/main/java/cn/iocoder/springboot/lab27/springwebflux/controller/UserController.java b/lab-27/lab-27-webflux-mongodb/src/main/java/cn/iocoder/springboot/lab27/springwebflux/controller/UserController.java
new file mode 100644
index 00000000..e1307faa
--- /dev/null
+++ b/lab-27/lab-27-webflux-mongodb/src/main/java/cn/iocoder/springboot/lab27/springwebflux/controller/UserController.java
@@ -0,0 +1,154 @@
+package cn.iocoder.springboot.lab27.springwebflux.controller;
+
+import cn.iocoder.springboot.lab27.springwebflux.dao.UserRepository;
+import cn.iocoder.springboot.lab27.springwebflux.dataobject.UserDO;
+import cn.iocoder.springboot.lab27.springwebflux.dto.UserAddDTO;
+import cn.iocoder.springboot.lab27.springwebflux.dto.UserUpdateDTO;
+import cn.iocoder.springboot.lab27.springwebflux.vo.UserVO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+import java.util.Date;
+import java.util.Objects;
+import java.util.function.Function;
+
+/**
+ * 用户 Controller
+ */
+@RestController
+@RequestMapping("/users")
+public class UserController {
+
+ @Autowired
+ private UserRepository userRepository;
+
+ /**
+ * 查询用户列表
+ *
+ * @return 用户列表
+ */
+ @GetMapping("/list")
+ public Flux list() {
+ // 返回列表
+ return userRepository.findAll()
+ .map(userDO -> new UserVO().setId(userDO.getId()).setUsername(userDO.getUsername()));
+ }
+
+ /**
+ * 获得指定用户编号的用户
+ *
+ * @param id 用户编号
+ * @return 用户
+ */
+ @GetMapping("/get")
+ public Mono get(@RequestParam("id") Integer id) {
+ // 返回
+ return userRepository.findById(id)
+ .map(userDO -> new UserVO().setId(userDO.getId()).setUsername(userDO.getUsername()));
+ }
+
+ /**
+ * 添加用户
+ *
+ * @param addDTO 添加用户信息 DTO
+ * @return 添加成功的用户编号
+ */
+ @PostMapping("add")
+ public Mono add(UserAddDTO addDTO) {
+ // 查询用户
+ Mono user = userRepository.findByUsername(addDTO.getUsername());
+
+ // 执行插入
+ return user.flatMap(new Function>() {
+
+ @Override
+ public Mono extends Integer> apply(UserDO userDO) {
+ if (userDO != null) {
+ // 返回 -1 表示插入失败。
+ // 实际上,一般是抛出 ServiceException 异常。因为这个示例项目里暂时没做全局异常的定义,所以暂时返回 -1 啦
+ return Mono.just(-1);
+ }
+ // 将 addDTO 转成 UserDO
+ userDO = new UserDO().setId((int) (System.currentTimeMillis() / 1000)) // 使用当前时间戳的描述,作为 ID 。
+ .setUsername(addDTO.getUsername())
+ .setPassword(addDTO.getPassword())
+ .setCreateTime(new Date());
+ // 插入数据库
+ return userRepository.save(userDO).map(UserDO::getId);
+ }
+
+ });
+ }
+
+ /**
+ * 更新指定用户编号的用户
+ *
+ * @param updateDTO 更新用户信息 DTO
+ * @return 是否修改成功
+ */
+ @PostMapping("/update")
+ public Mono update(UserUpdateDTO updateDTO) {
+ // 查询用户
+ Mono user = userRepository.findById(updateDTO.getId());
+
+ // 执行更新
+ return user.flatMap(new Function>() {
+
+ @Override
+ public Mono apply(UserDO userDO) {
+ // 如果不存在该用户,则直接返回 false 失败
+ if (userDO == null) {
+ return Mono.just(false);
+ }
+ // 查询用户是否存在
+ return userRepository.findByUsername(updateDTO.getUsername())
+ .flatMap(new Function>() {
+
+ @Override
+ public Mono extends Boolean> apply(UserDO usernameUserDO) {
+ // 如果用户名已经使用
+ if (usernameUserDO != null && !Objects.equals(updateDTO.getId(), usernameUserDO.getId())) {
+ return Mono.just(false);
+ }
+ // 执行更新
+ userDO.setUsername(updateDTO.getUsername());
+ userDO.setPassword(updateDTO.getPassword());
+ return userRepository.save(userDO).map(userDO -> true); // 返回 true 成功
+ }
+
+ });
+ }
+
+ });
+ }
+
+ /**
+ * 删除指定用户编号的用户
+ *
+ * @param id 用户编号
+ * @return 是否删除成功
+ */
+ @PostMapping("/delete") // URL 修改成 /delete ,RequestMethod 改成 DELETE
+ public Mono delete(@RequestParam("id") Integer id) {
+ // 查询用户
+ Mono user = userRepository.findById(id);
+
+ // 执行删除。这里仅仅是示例,项目中不要物理删除,而是标记删除
+ return user.flatMap(new Function>() {
+
+ @Override
+ public Mono extends Boolean> apply(UserDO userDO) {
+ // 如果不存在该用户,则直接返回 false 失败
+ if (userDO == null) {
+ return Mono.just(false);
+ }
+ // 执行删除
+ return userRepository.deleteById(id).map(aVoid -> true); // 返回 true 成功
+ }
+
+ });
+ }
+
+}
diff --git a/lab-27/lab-27-webflux-mongodb/src/main/java/cn/iocoder/springboot/lab27/springwebflux/dao/UserRepository.java b/lab-27/lab-27-webflux-mongodb/src/main/java/cn/iocoder/springboot/lab27/springwebflux/dao/UserRepository.java
new file mode 100644
index 00000000..9ee61f79
--- /dev/null
+++ b/lab-27/lab-27-webflux-mongodb/src/main/java/cn/iocoder/springboot/lab27/springwebflux/dao/UserRepository.java
@@ -0,0 +1,11 @@
+package cn.iocoder.springboot.lab27.springwebflux.dao;
+
+import cn.iocoder.springboot.lab27.springwebflux.dataobject.UserDO;
+import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
+import reactor.core.publisher.Mono;
+
+public interface UserRepository extends ReactiveMongoRepository {
+
+ Mono findByUsername(String username);
+
+}
diff --git a/lab-27/lab-27-webflux-mongodb/src/main/java/cn/iocoder/springboot/lab27/springwebflux/dataobject/UserDO.java b/lab-27/lab-27-webflux-mongodb/src/main/java/cn/iocoder/springboot/lab27/springwebflux/dataobject/UserDO.java
new file mode 100644
index 00000000..6402c7f5
--- /dev/null
+++ b/lab-27/lab-27-webflux-mongodb/src/main/java/cn/iocoder/springboot/lab27/springwebflux/dataobject/UserDO.java
@@ -0,0 +1,75 @@
+package cn.iocoder.springboot.lab27.springwebflux.dataobject;
+
+import org.springframework.data.annotation.Id;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+import java.util.Date;
+
+/**
+ * 用户 DO
+ */
+@Document(collection = "User")
+public class UserDO {
+
+ @Id
+ private Integer id;
+ /**
+ * 账号
+ */
+ private String username;
+ /**
+ * 密码
+ */
+ private String password;
+ /**
+ * 创建时间
+ */
+ private Date createTime;
+
+ public Integer getId() {
+ return id;
+ }
+
+ public UserDO setId(Integer id) {
+ this.id = id;
+ return this;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public UserDO setUsername(String username) {
+ this.username = username;
+ return this;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public UserDO setPassword(String password) {
+ this.password = password;
+ return this;
+ }
+
+ public Date getCreateTime() {
+ return createTime;
+ }
+
+ public UserDO setCreateTime(Date createTime) {
+ this.createTime = createTime;
+ return this;
+ }
+
+ @Override
+ public String toString() {
+ return "UserDO{" +
+ "id=" + id +
+ ", username='" + username + '\'' +
+ ", password='" + password + '\'' +
+ ", createTime=" + createTime +
+ '}';
+ }
+
+}
diff --git a/lab-27/lab-27-webflux-mongodb/src/main/java/cn/iocoder/springboot/lab27/springwebflux/dto/UserAddDTO.java b/lab-27/lab-27-webflux-mongodb/src/main/java/cn/iocoder/springboot/lab27/springwebflux/dto/UserAddDTO.java
new file mode 100644
index 00000000..32674a82
--- /dev/null
+++ b/lab-27/lab-27-webflux-mongodb/src/main/java/cn/iocoder/springboot/lab27/springwebflux/dto/UserAddDTO.java
@@ -0,0 +1,35 @@
+package cn.iocoder.springboot.lab27.springwebflux.dto;
+
+/**
+ * 用户添加 DTO
+ */
+public class UserAddDTO {
+
+ /**
+ * 账号
+ */
+ private String username;
+ /**
+ * 密码
+ */
+ private String password;
+
+ public String getUsername() {
+ return username;
+ }
+
+ public UserAddDTO setUsername(String username) {
+ this.username = username;
+ return this;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public UserAddDTO setPassword(String password) {
+ this.password = password;
+ return this;
+ }
+
+}
diff --git a/lab-27/lab-27-webflux-mongodb/src/main/java/cn/iocoder/springboot/lab27/springwebflux/dto/UserUpdateDTO.java b/lab-27/lab-27-webflux-mongodb/src/main/java/cn/iocoder/springboot/lab27/springwebflux/dto/UserUpdateDTO.java
new file mode 100644
index 00000000..b02edb31
--- /dev/null
+++ b/lab-27/lab-27-webflux-mongodb/src/main/java/cn/iocoder/springboot/lab27/springwebflux/dto/UserUpdateDTO.java
@@ -0,0 +1,45 @@
+package cn.iocoder.springboot.lab27.springwebflux.dto;
+
+public class UserUpdateDTO {
+
+ /**
+ * 编号
+ */
+ private Integer id;
+ /**
+ * 账号
+ */
+ private String username;
+ /**
+ * 密码
+ */
+ private String password;
+
+ public Integer getId() {
+ return id;
+ }
+
+ public UserUpdateDTO setId(Integer id) {
+ this.id = id;
+ return this;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public UserUpdateDTO setUsername(String username) {
+ this.username = username;
+ return this;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public UserUpdateDTO setPassword(String password) {
+ this.password = password;
+ return this;
+ }
+
+}
diff --git a/lab-27/lab-27-webflux-mongodb/src/main/java/cn/iocoder/springboot/lab27/springwebflux/service/UserService.java b/lab-27/lab-27-webflux-mongodb/src/main/java/cn/iocoder/springboot/lab27/springwebflux/service/UserService.java
new file mode 100644
index 00000000..00332350
--- /dev/null
+++ b/lab-27/lab-27-webflux-mongodb/src/main/java/cn/iocoder/springboot/lab27/springwebflux/service/UserService.java
@@ -0,0 +1,13 @@
+package cn.iocoder.springboot.lab27.springwebflux.service;
+
+import cn.iocoder.springboot.lab27.springwebflux.vo.UserVO;
+import org.springframework.stereotype.Service;
+
+@Service
+public class UserService {
+
+ public UserVO get(Integer id) {
+ return new UserVO().setId(id).setUsername("test");
+ }
+
+}
diff --git a/lab-27/lab-27-webflux-mongodb/src/main/java/cn/iocoder/springboot/lab27/springwebflux/vo/UserVO.java b/lab-27/lab-27-webflux-mongodb/src/main/java/cn/iocoder/springboot/lab27/springwebflux/vo/UserVO.java
new file mode 100644
index 00000000..7dd64075
--- /dev/null
+++ b/lab-27/lab-27-webflux-mongodb/src/main/java/cn/iocoder/springboot/lab27/springwebflux/vo/UserVO.java
@@ -0,0 +1,35 @@
+package cn.iocoder.springboot.lab27.springwebflux.vo;
+
+/**
+ * 用户 VO
+ */
+public class UserVO {
+
+ /**
+ * 编号
+ */
+ private Integer id;
+ /**
+ * 账号
+ */
+ private String username;
+
+ public Integer getId() {
+ return id;
+ }
+
+ public UserVO setId(Integer id) {
+ this.id = id;
+ return this;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public UserVO setUsername(String username) {
+ this.username = username;
+ return this;
+ }
+
+}
diff --git a/lab-27/lab-27-webflux-mongodb/src/main/resources/application.yaml b/lab-27/lab-27-webflux-mongodb/src/main/resources/application.yaml
new file mode 100644
index 00000000..9d5d76f0
--- /dev/null
+++ b/lab-27/lab-27-webflux-mongodb/src/main/resources/application.yaml
@@ -0,0 +1,18 @@
+spring:
+ data:
+ # MongoDB 配置项,对应 MongoProperties 类
+ mongodb:
+ host: 127.0.0.1
+ port: 27017
+ database: yourdatabase
+ username: test01
+ password: password01
+ # 上述属性,也可以只配置 uri
+
+logging:
+ level:
+ org:
+ springframework:
+ data:
+ mongodb:
+ core: DEBUG # 打印 mongodb 操作的具体语句。生产环境下,不建议开启。
diff --git a/lab-27/pom.xml b/lab-27/pom.xml
index d9dc6611..74c498ec 100644
--- a/lab-27/pom.xml
+++ b/lab-27/pom.xml
@@ -15,6 +15,7 @@
lab-27-webflux-01
lab-27-webflux-02
lab-27-webflux-03
+ lab-27-webflux-mongodb