From 3500a3cc68b2a92c07469cf9d806281b7800d60f Mon Sep 17 00:00:00 2001 From: YunaiV <> Date: Tue, 26 Nov 2019 22:55:35 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=20webflux=20mysql=20+=20?= =?UTF-8?q?=E4=BA=8B=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lab-27/lab-27-webflux-r2dbc/pom.xml | 58 +++++++ .../lab27/springwebflux/Application.java | 13 ++ .../config/DatabaseConfiguration.java | 35 ++++ .../controller/UserController.java | 161 ++++++++++++++++++ .../springwebflux/dao/UserRepository.java | 13 ++ .../springwebflux/dataobject/UserDO.java | 75 ++++++++ .../lab27/springwebflux/dto/UserAddDTO.java | 35 ++++ .../springwebflux/dto/UserUpdateDTO.java | 45 +++++ .../lab27/springwebflux/vo/UserVO.java | 35 ++++ .../src/main/resources/application.yaml | 10 ++ .../target/classes/application.yaml | 10 ++ lab-27/pom.xml | 2 +- 12 files changed, 491 insertions(+), 1 deletion(-) create mode 100644 lab-27/lab-27-webflux-r2dbc/pom.xml create mode 100644 lab-27/lab-27-webflux-r2dbc/src/main/java/cn/iocoder/springboot/lab27/springwebflux/Application.java create mode 100644 lab-27/lab-27-webflux-r2dbc/src/main/java/cn/iocoder/springboot/lab27/springwebflux/config/DatabaseConfiguration.java create mode 100644 lab-27/lab-27-webflux-r2dbc/src/main/java/cn/iocoder/springboot/lab27/springwebflux/controller/UserController.java create mode 100644 lab-27/lab-27-webflux-r2dbc/src/main/java/cn/iocoder/springboot/lab27/springwebflux/dao/UserRepository.java create mode 100644 lab-27/lab-27-webflux-r2dbc/src/main/java/cn/iocoder/springboot/lab27/springwebflux/dataobject/UserDO.java create mode 100644 lab-27/lab-27-webflux-r2dbc/src/main/java/cn/iocoder/springboot/lab27/springwebflux/dto/UserAddDTO.java create mode 100644 lab-27/lab-27-webflux-r2dbc/src/main/java/cn/iocoder/springboot/lab27/springwebflux/dto/UserUpdateDTO.java create mode 100644 lab-27/lab-27-webflux-r2dbc/src/main/java/cn/iocoder/springboot/lab27/springwebflux/vo/UserVO.java create mode 100644 lab-27/lab-27-webflux-r2dbc/src/main/resources/application.yaml create mode 100644 lab-27/lab-27-webflux-r2dbc/target/classes/application.yaml diff --git a/lab-27/lab-27-webflux-r2dbc/pom.xml b/lab-27/lab-27-webflux-r2dbc/pom.xml new file mode 100644 index 00000000..4ef33eb1 --- /dev/null +++ b/lab-27/lab-27-webflux-r2dbc/pom.xml @@ -0,0 +1,58 @@ + + + + org.springframework.boot + spring-boot-starter-parent + 2.2.1.RELEASE + + + 4.0.0 + + lab-27-webflux-r2dbc + + + + + org.springframework.boot + spring-boot-starter-webflux + 2.2.1.RELEASE + + + + + org.springframework.boot.experimental + spring-boot-starter-data-r2dbc + 0.1.0.M2 + + + + com.github.jasync-sql + jasync-r2dbc-mysql + 1.0.11 + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + + spring-libs-snapshot + https://repo.spring.io/libs-snapshot + + + + jcenter + https://jcenter.bintray.com/ + + + + diff --git a/lab-27/lab-27-webflux-r2dbc/src/main/java/cn/iocoder/springboot/lab27/springwebflux/Application.java b/lab-27/lab-27-webflux-r2dbc/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-r2dbc/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-r2dbc/src/main/java/cn/iocoder/springboot/lab27/springwebflux/config/DatabaseConfiguration.java b/lab-27/lab-27-webflux-r2dbc/src/main/java/cn/iocoder/springboot/lab27/springwebflux/config/DatabaseConfiguration.java new file mode 100644 index 00000000..686e107e --- /dev/null +++ b/lab-27/lab-27-webflux-r2dbc/src/main/java/cn/iocoder/springboot/lab27/springwebflux/config/DatabaseConfiguration.java @@ -0,0 +1,35 @@ +package cn.iocoder.springboot.lab27.springwebflux.config; + +import com.github.jasync.r2dbc.mysql.JasyncConnectionFactory; +import com.github.jasync.sql.db.mysql.pool.MySQLConnectionFactory; +import io.r2dbc.spi.ConnectionFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +@Configuration +@EnableTransactionManagement +public class DatabaseConfiguration { + +// @Bean +// @ConfigurationProperties("spring.jasync.r2dbc") +// public com.github.jasync.sql.db.Configuration configuration() { +// return new com.github.jasync.sql.db.Configuration(""); +// } + + @Bean + public ConnectionFactory connectionFactory() { +// com.github.jasync.sql.db.Configuration configuration +//// = URLParser.INSTANCE.parseOrDie("mysql://root:@localhost:3306/lab-27-webflux-r2dbc", StandardCharsets.UTF_8); +// = URLParser.INSTANCE.parseOrDie("mysql://lab-27-webflux-r2dbc:0ed86@11-r2Dbc123@47.112.193.81:3306/lab-27-webflux-r2dbc", StandardCharsets.UTF_8); + com.github.jasync.sql.db.Configuration configuration = new com.github.jasync.sql.db.Configuration( + "lab-27-webflux-r2dbc", + "47.112.193.81", + 3306, + "0ed86@11-r2Dbc123", + "lab-27-webflux-r2dbc" + ); + return new JasyncConnectionFactory(new MySQLConnectionFactory(configuration)); + } + +} diff --git a/lab-27/lab-27-webflux-r2dbc/src/main/java/cn/iocoder/springboot/lab27/springwebflux/controller/UserController.java b/lab-27/lab-27-webflux-r2dbc/src/main/java/cn/iocoder/springboot/lab27/springwebflux/controller/UserController.java new file mode 100644 index 00000000..ff476dc9 --- /dev/null +++ b/lab-27/lab-27-webflux-r2dbc/src/main/java/cn/iocoder/springboot/lab27/springwebflux/controller/UserController.java @@ -0,0 +1,161 @@ +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 { + + private static final UserDO USER_NULL = new UserDO(); + + @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") +// @Transactional + public Mono add(UserAddDTO addDTO) { + // 查询用户 + Mono user = userRepository.findByUsername(addDTO.getUsername()); + + // 执行插入 + return user.defaultIfEmpty(USER_NULL) // 设置 USER_NULL 作为 null 的情况,否则 flatMap 不会往下走 + .flatMap(new Function>() { + + @Override + public Mono apply(UserDO userDO) { + if (userDO != USER_NULL) { + // 返回 -1 表示插入失败。 + // 实际上,一般是抛出 ServiceException 异常。因为这个示例项目里暂时没做全局异常的定义,所以暂时返回 -1 啦 + return Mono.just(-1); + } + // 将 addDTO 转成 UserDO + userDO = new UserDO() + .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.defaultIfEmpty(USER_NULL) // 设置 USER_NULL 作为 null 的情况,否则 flatMap 不会往下走 + .flatMap(new Function>() { + + @Override + public Mono apply(UserDO userDO) { + // 如果不存在该用户,则直接返回 false 失败 + if (userDO == USER_NULL) { + return Mono.just(false); + } + // 查询用户是否存在 + return userRepository.findByUsername(updateDTO.getUsername()) + .defaultIfEmpty(USER_NULL) // 设置 USER_NULL 作为 null 的情况,否则 flatMap 不会往下走 + .flatMap(new Function>() { + + @Override + public Mono apply(UserDO usernameUserDO) { + // 如果用户名已经使用(该用户名对应的 id 不是自己,说明就已经被使用了) + if (usernameUserDO != USER_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.defaultIfEmpty(USER_NULL) // 设置 USER_NULL 作为 null 的情况,否则 flatMap 不会往下走 + .flatMap(new Function>() { + + @Override + public Mono apply(UserDO userDO) { + // 如果不存在该用户,则直接返回 false 失败 + if (userDO == USER_NULL) { + return Mono.just(false); + } + // 执行删除 + return userRepository.deleteById(id).map(aVoid -> true); // 返回 true 成功 + } + + }); + } + +} diff --git a/lab-27/lab-27-webflux-r2dbc/src/main/java/cn/iocoder/springboot/lab27/springwebflux/dao/UserRepository.java b/lab-27/lab-27-webflux-r2dbc/src/main/java/cn/iocoder/springboot/lab27/springwebflux/dao/UserRepository.java new file mode 100644 index 00000000..feeecb7b --- /dev/null +++ b/lab-27/lab-27-webflux-r2dbc/src/main/java/cn/iocoder/springboot/lab27/springwebflux/dao/UserRepository.java @@ -0,0 +1,13 @@ +package cn.iocoder.springboot.lab27.springwebflux.dao; + +import cn.iocoder.springboot.lab27.springwebflux.dataobject.UserDO; +import org.springframework.data.r2dbc.repository.query.Query; +import org.springframework.data.repository.reactive.ReactiveCrudRepository; +import reactor.core.publisher.Mono; + +public interface UserRepository extends ReactiveCrudRepository { + + @Query("SELECT id FROM users u WHERE u.username = :username") + Mono findByUsername(String username); + +} diff --git a/lab-27/lab-27-webflux-r2dbc/src/main/java/cn/iocoder/springboot/lab27/springwebflux/dataobject/UserDO.java b/lab-27/lab-27-webflux-r2dbc/src/main/java/cn/iocoder/springboot/lab27/springwebflux/dataobject/UserDO.java new file mode 100644 index 00000000..fc715d36 --- /dev/null +++ b/lab-27/lab-27-webflux-r2dbc/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.relational.core.mapping.Table; + +import java.util.Date; + +/** + * 用户 DO + */ +@Table(value = "users") +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-r2dbc/src/main/java/cn/iocoder/springboot/lab27/springwebflux/dto/UserAddDTO.java b/lab-27/lab-27-webflux-r2dbc/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-r2dbc/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-r2dbc/src/main/java/cn/iocoder/springboot/lab27/springwebflux/dto/UserUpdateDTO.java b/lab-27/lab-27-webflux-r2dbc/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-r2dbc/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-r2dbc/src/main/java/cn/iocoder/springboot/lab27/springwebflux/vo/UserVO.java b/lab-27/lab-27-webflux-r2dbc/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-r2dbc/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-r2dbc/src/main/resources/application.yaml b/lab-27/lab-27-webflux-r2dbc/src/main/resources/application.yaml new file mode 100644 index 00000000..fc339a5a --- /dev/null +++ b/lab-27/lab-27-webflux-r2dbc/src/main/resources/application.yaml @@ -0,0 +1,10 @@ +spring: + jasync: + r2dbc: + host: 47.112.193.81 + port: 3306 + database: lab-27-webflux-r2dbc + username: lab-27-webflux-r2dbc + password: 0ed86@11-r2Dbc123 + + diff --git a/lab-27/lab-27-webflux-r2dbc/target/classes/application.yaml b/lab-27/lab-27-webflux-r2dbc/target/classes/application.yaml new file mode 100644 index 00000000..fc339a5a --- /dev/null +++ b/lab-27/lab-27-webflux-r2dbc/target/classes/application.yaml @@ -0,0 +1,10 @@ +spring: + jasync: + r2dbc: + host: 47.112.193.81 + port: 3306 + database: lab-27-webflux-r2dbc + username: lab-27-webflux-r2dbc + password: 0ed86@11-r2Dbc123 + + diff --git a/lab-27/pom.xml b/lab-27/pom.xml index 647ed7a9..b83c9efa 100644 --- a/lab-27/pom.xml +++ b/lab-27/pom.xml @@ -18,7 +18,7 @@ lab-27-webflux-mongodb lab-27-webflux-redis lab-27-webflux-elasticsearch - lab-27-webflux-jpa + lab-27-webflux-r2dbc