最近接触webflux
,网上找了些例子感觉没有纯搭建的,而且实际使用的一些坑都没介绍,下面是我搭的项目和解决的方案,仅供参考
创建数据库
新建web_flux_demo
表
create table web_flux_demo
(
pk_id varchar(36) not null comment '主键'
primary key,
username varchar(255) null,
password varchar(255) null,
age int null,
birth timestamp null
)
comment 'webfluxdemo';
新建maven
工程并添加依赖
注意:
spring-boot-starter-parent:2.3.0
以上才管理了r2dbc
版本
<?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.4.0</version>
<relativePath></relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>gdc-gis</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-r2dbc</artifactId>
</dependency>
<dependency>
<groupId>dev.miku</groupId>
<artifactId>r2dbc-mysql</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.5.9</version>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
</project>
配置文件
spring:
r2dbc:
url: r2dbcs:mysql://127.0.0.1:23307/demo
username: root
password: zydcca1@mysql
实体类
FluxBaseEntity
@Column("pk_id")
表内字段名字
重写isNew()
方法解决新增对象带id
时报错Row with Id [xxx] does not exist
import cn.hutool.core.util.StrUtil;
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.domain.Persistable;
import org.springframework.data.relational.core.mapping.Column;
import java.io.Serializable;
/**
* Description: 基类 实现 Persistable 接口,并实现 isNew 方法,<br>
* Date: 2022-9-7 14:47<br>
*
* @author moon
* @since 1.0.0
*/
@Data
public class FluxBaseEntity implements Persistable<String>,Serializable {
/**
* 主键
*/
@Id
@Column("pk_id") // 表内字段名字
private String id;
/**
* 在实体新怎和修改方法时会走该方法,来判断需要新增还是修改
* @return bool
*/
@Override
public boolean isNew() {
return StrUtil.isBlank(this.id);
}
}
WebFluxDemoEntity
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.relational.core.mapping.Table;
import java.time.LocalDate;
/**
* Description: <br>
* Date: 2022-9-6 10:11<br>
*
* @author moon
* @since 1.0.0
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@Table("web_flux_demo") // 标志数据表名
public class WebFluxDemoEntity extends FluxBaseEntity {
private String username;
private String password;
private Integer age;
/**
* 注意使用 LocalDate 不能使用util下date
*/
private LocalDate birth;
}
Controller
import com.geniuses.gis.web.entity.WebFluxDemoEntity;
import com.geniuses.gis.web.dao.WebFluxDemoDao;
import com.sun.xml.internal.bind.v2.model.core.ID;
import org.reactivestreams.Publisher;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.List;
/**
* Description: <br>
* Date: 2022-9-5 16:52<br>
*
* @author moon
* @since 1.0.0
*/
@Component
@RestController
@RequestMapping("/demo")
public class WebFluxDemoController {
private WebFluxDemoDao webFluxDemoDao;
public WebFluxDemoController(WebFluxDemoDao webFluxDemoDao) {
this.webFluxDemoDao = webFluxDemoDao;
}
/**
* 返回字符串
* @return String
*/
@GetMapping("/hello")
public Mono<String> hello() {
return Mono.just("Hello, WebFlux !");
}
/**
* 获取对象列表
* @return 对象list
*/
@GetMapping
public Flux<WebFluxDemoEntity> list() {
return webFluxDemoDao.findAll();
}
/**
* 获取单个对象
* @param id 主键
* @return 单个对象
*/
@GetMapping("/{id}")
public Mono<WebFluxDemoEntity> get(@PathVariable String id) {
return webFluxDemoDao.findById(id);
}
/**
* 新增/修改
* @param webFluxDemoEntity 对象
* @return 新增/修改后的对象
*/
@PostMapping
public Mono<WebFluxDemoEntity> save(@RequestBody WebFluxDemoEntity webFluxDemoEntity) {
return webFluxDemoDao.save(webFluxDemoEntity);
}
/**
* 批量删除
* @param ids 主键数组
* @return void
*/
@DeleteMapping
public Mono<Void> del(String... ids) {
return webFluxDemoDao.deleteById(Flux.fromArray(ids));
}
}
Dao
import com.geniuses.gis.web.entity.WebFluxDemoEntity;
import org.springframework.data.repository.reactive.ReactiveCrudRepository;
import java.util.List;
/**
* Description: <br>
* Date: 2022-9-6 11:02<br>
*
* @author moon
* @since 1.0.0
*/
public interface WebFluxDemoDao extends ReactiveCrudRepository<WebFluxDemoEntity,String> {
}
config
EntitySaveCallBackConfig
数据保存前回调,可解决数据新增时无主键报错
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.geniuses.gis.web.entity.FluxBaseEntity;
import org.reactivestreams.Publisher;
import org.springframework.data.r2dbc.mapping.OutboundRow;
import org.springframework.data.r2dbc.mapping.event.BeforeSaveCallback;
import org.springframework.data.relational.core.sql.SqlIdentifier;
import org.springframework.r2dbc.core.Parameter;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;
/**
* Description: entity保存前回调 <br>
* Date: 2022-9-7 14:45<br>
*
* @author moon
* @since 1.0.0
*/
@Component
public class EntitySaveCallBackConfig implements BeforeSaveCallback<FluxBaseEntity> {
/**
* 保存前回调方法
* @param entity 待保存实体
* @param outboundRow 数据库字段及类型
* @param sqlIdentifier 数据库表名
* @return Publisher<FluxBaseEntity>
*/
@Override
public Publisher<FluxBaseEntity> onBeforeSave(FluxBaseEntity entity, OutboundRow outboundRow, SqlIdentifier sqlIdentifier) {
if (StrUtil.isBlank(entity.getId())) {
String simpleUUID = IdUtil.simpleUUID();
// 回填主键(前端回显时用)
entity.setId(simpleUUID);
// 数据库新增主键
outboundRow.put("pk_id",Parameter.from(simpleUUID));
}
return Mono.just(entity);
}
}
启动类
Application
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
/**
* Description: <br>
* Date: 2022-8-23 14:57<br>
*
* @author moon
* @since 1.0.0
*/
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(GisApplication.class, args);
}
}
至此项目搭建完成,启动后访问接口测试即可