mirror of
https://gitee.com/yudaocode/SpringBoot-Labs.git
synced 2026-09-03 05:53:54 +08:00
增加 webflux mysql + 事务
This commit is contained in:
58
lab-27/lab-27-webflux-r2dbc/pom.xml
Normal file
58
lab-27/lab-27-webflux-r2dbc/pom.xml
Normal file
@@ -0,0 +1,58 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.2.1.RELEASE</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>lab-27-webflux-r2dbc</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<!-- 实现对 Spring WebFlux 的自动化配置 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-webflux</artifactId>
|
||||
<version>2.2.1.RELEASE</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 自动化配置响应式的 Spring Data R2DBC -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot.experimental</groupId>
|
||||
<artifactId>spring-boot-starter-data-r2dbc</artifactId>
|
||||
<version>0.1.0.M2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.jasync-sql</groupId>
|
||||
<artifactId>jasync-r2dbc-mysql</artifactId>
|
||||
<version>1.0.11</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 方便等会写单元测试 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<repositories>
|
||||
<!-- 引入 Spring 的快照仓库 -->
|
||||
<repository>
|
||||
<id>spring-libs-snapshot</id>
|
||||
<url>https://repo.spring.io/libs-snapshot</url>
|
||||
</repository>
|
||||
<!-- 引入 Jcenter 的快照仓库 -->
|
||||
<repository>
|
||||
<id>jcenter</id>
|
||||
<url>https://jcenter.bintray.com/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
</project>
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<UserVO> list() {
|
||||
// 返回列表
|
||||
return userRepository.findAll()
|
||||
.map(userDO -> new UserVO().setId(userDO.getId()).setUsername(userDO.getUsername()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得指定用户编号的用户
|
||||
*
|
||||
* @param id 用户编号
|
||||
* @return 用户
|
||||
*/
|
||||
@GetMapping("/get")
|
||||
public Mono<UserVO> 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<Integer> add(UserAddDTO addDTO) {
|
||||
// 查询用户
|
||||
Mono<UserDO> user = userRepository.findByUsername(addDTO.getUsername());
|
||||
|
||||
// 执行插入
|
||||
return user.defaultIfEmpty(USER_NULL) // 设置 USER_NULL 作为 null 的情况,否则 flatMap 不会往下走
|
||||
.flatMap(new Function<UserDO, Mono<Integer>>() {
|
||||
|
||||
@Override
|
||||
public Mono<Integer> 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<Boolean> update(UserUpdateDTO updateDTO) {
|
||||
// 查询用户
|
||||
Mono<UserDO> user = userRepository.findById(updateDTO.getId());
|
||||
|
||||
// 执行更新
|
||||
return user.defaultIfEmpty(USER_NULL) // 设置 USER_NULL 作为 null 的情况,否则 flatMap 不会往下走
|
||||
.flatMap(new Function<UserDO, Mono<Boolean>>() {
|
||||
|
||||
@Override
|
||||
public Mono<Boolean> 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<UserDO, Mono<? extends Boolean>>() {
|
||||
|
||||
@Override
|
||||
public Mono<? extends Boolean> 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<Boolean> delete(@RequestParam("id") Integer id) {
|
||||
// 查询用户
|
||||
Mono<UserDO> user = userRepository.findById(id);
|
||||
|
||||
// 执行删除。这里仅仅是示例,项目中不要物理删除,而是标记删除
|
||||
return user.defaultIfEmpty(USER_NULL) // 设置 USER_NULL 作为 null 的情况,否则 flatMap 不会往下走
|
||||
.flatMap(new Function<UserDO, Mono<Boolean>>() {
|
||||
|
||||
@Override
|
||||
public Mono<Boolean> apply(UserDO userDO) {
|
||||
// 如果不存在该用户,则直接返回 false 失败
|
||||
if (userDO == USER_NULL) {
|
||||
return Mono.just(false);
|
||||
}
|
||||
// 执行删除
|
||||
return userRepository.deleteById(id).map(aVoid -> true); // 返回 true 成功
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<UserDO, Integer> {
|
||||
|
||||
@Query("SELECT id FROM users u WHERE u.username = :username")
|
||||
Mono<UserDO> findByUsername(String username);
|
||||
|
||||
}
|
||||
@@ -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 +
|
||||
'}';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
|
||||
|
||||
10
lab-27/lab-27-webflux-r2dbc/target/classes/application.yaml
Normal file
10
lab-27/lab-27-webflux-r2dbc/target/classes/application.yaml
Normal file
@@ -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
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
<module>lab-27-webflux-mongodb</module>
|
||||
<module>lab-27-webflux-redis</module>
|
||||
<module>lab-27-webflux-elasticsearch</module>
|
||||
<module>lab-27-webflux-jpa</module>
|
||||
<module>lab-27-webflux-r2dbc</module>
|
||||
</modules>
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user