目录
1、pom.xml文件
<?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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.0</version>
</parent>
<groupId>com.coffee</groupId>
<artifactId>webflux-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<mybatis.verison>2.2.2</mybatis.verison>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-r2dbc</artifactId>
</dependency>
<!-- r2dbc 连接池 -->
<dependency>
<groupId>io.r2dbc</groupId>
<artifactId>r2dbc-pool</artifactId>
</dependency>
<!--r2dbc mysql 库-->
<dependency>
<groupId>dev.miku</groupId>
<artifactId>r2dbc-mysql</artifactId>
<version>0.8.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2、主启动类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class WebFluxApplication {
public static void main(String[] args) {
SpringApplication.run(WebFluxApplication.class, args);
}
}
3、实体类
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.Id;
import org.springframework.data.relational.core.mapping.Column;
import org.springframework.data.relational.core.mapping.Table;
import java.io.Serializable;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Table("people")
public class People implements Serializable {
private static final long serialVersionUID = 620950479129453625L;
@Id
@Column("id")
private Integer id;
@Column("username")
private String username;
@Column("gender")
private String gender;
@Column("address")
private String address;
}
4、dao层
import com.coffee.webflux.samples.entity.People;
import org.springframework.data.r2dbc.repository.R2dbcRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface PeopleRepository extends R2dbcRepository<People, Integer> {
}
5、Handler层
方式一:使用PeopleRepository
import com.coffee.webflux.samples.dao.PeopleRepository;
import com.coffee.webflux.samples.entity.People;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;
import javax.annotation.Resource;
@Component
public class PeopleRepositoryHandler {
@Resource
private PeopleRepository peopleRepository;
// 查询所有
public Mono<ServerResponse> listPeople(ServerRequest request) {
return ServerResponse.ok()
.contentType(MediaType.APPLICATION_JSON)
.body(peopleRepository.findAll(), People.class);
}
// 根据主键查询
public Mono<ServerResponse> findPeopleById(ServerRequest request) {
int personId = Integer.parseInt(request.pathVariable("id"));
return peopleRepository.findById(personId)
.flatMap(people -> ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).bodyValue(people))
.switchIfEmpty(ServerResponse.notFound().build());
}
// 根据主键删除
public Mono<ServerResponse> deletePeople(ServerRequest request) {
return this.peopleRepository.findById(Integer.parseInt(request.pathVariable("id")))
.flatMap(user -> ServerResponse
.noContent()
.build(this.peopleRepository.delete(user)))
.switchIfEmpty(ServerResponse.notFound().build());
}
// 插入数据
public Mono<ServerResponse> insertPeople(ServerRequest request) {
Mono<People> peopleMono = request.bodyToMono(People.class)
.flatMap(people -> peopleRepository.save(people));
return ServerResponse.ok().body(peopleMono, People.class);
}
}
方式二:使用R2dbcEntityTemplate
import com.coffee.webflux.samples.entity.People;
import org.springframework.data.r2dbc.core.R2dbcEntityTemplate;
import org.springframework.data.relational.core.query.Query;
import org.springframework.data.relational.core.query.Update;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import javax.annotation.Resource;
import static org.springframework.data.relational.core.query.Criteria.where;
@Component
public class PeopleR2dbcTemplateHandler {
@Resource
private R2dbcEntityTemplate r2dbcEntityTemplate;
// 查询所有
public Mono<ServerResponse> listPeople(ServerRequest request) {
Flux<People> peopleFlux = r2dbcEntityTemplate.select(Query.empty(), People.class);
return ServerResponse.ok()
.contentType(MediaType.APPLICATION_JSON)
.body(peopleFlux, People.class);
}
// 根据主键查询
public Mono<ServerResponse> findPeopleById(ServerRequest request) {
int personId = Integer.parseInt(request.pathVariable("id"));
Mono<People> peopleMono = r2dbcEntityTemplate.selectOne(Query.query(where("id").is(personId)), People.class);
return peopleMono
.flatMap(people -> ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).bodyValue(people))
.switchIfEmpty(ServerResponse.notFound().build());
}
// 根据名字模糊查询
public Mono<ServerResponse> findPeopleByUsernameContains(ServerRequest request) {
String name = request.pathVariable("name");
Flux<People> peopleFlux = r2dbcEntityTemplate.select(People.class)
.matching(Query.query(where("username").like("%" + name + "%")).limit(10).offset(0))
.all();
return ServerResponse.ok()
.contentType(MediaType.APPLICATION_JSON)
.body(peopleFlux, People.class);
}
// 根据主键删除
public Mono<ServerResponse> deletePeople(ServerRequest request) {
int personId = Integer.parseInt(request.pathVariable("id"));
Mono<Integer> deleteMono = r2dbcEntityTemplate.delete(Query.query(where("id").is(personId)), People.class);
return ServerResponse.ok()
.build(deleteMono.then());
}
// 根据主键进行更新
public Mono<ServerResponse> updatePeople(ServerRequest request) {
Mono<Integer> resultMono = request.bodyToMono(People.class)
.flatMap(people -> r2dbcEntityTemplate.update(Query.query(where("id").is(people.getId())),
Update.update("username", people.getUsername())
.set("address", people.getAddress()),
People.class));
return ServerResponse.ok()
.build(resultMono.then());
}
// 插入数据
public Mono<ServerResponse> insertPeople(ServerRequest request) {
Mono<People> peopleMono = request.bodyToMono(People.class)
.flatMap(people -> r2dbcEntityTemplate.insert(People.class).using(people));
return ServerResponse.ok().body(peopleMono, People.class);
}
}
6、router层
import com.coffee.webflux.samples.handler.PeopleR2dbcTemplateHandler;
import com.coffee.webflux.samples.handler.PeopleRepositoryHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.server.RequestPredicates;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerResponse;
import javax.annotation.Resource;
@Configuration
public class PeopleRouter {
@Resource
private PeopleRepositoryHandler peopleRepositoryHandler;
@Resource
private PeopleR2dbcTemplateHandler peopleR2dbcTemplateHandler;
@Bean
public RouterFunction<ServerResponse> peopleRepositoryRoutes() {
return RouterFunctions.route()
.GET("/repository/listPeople", RequestPredicates.accept(MediaType.APPLICATION_JSON), peopleRepositoryHandler::listPeople)
.GET("/repository/getPeople/{id}", RequestPredicates.accept(MediaType.APPLICATION_JSON), peopleRepositoryHandler::findPeopleById)
.POST("/repository/insertPeople", RequestPredicates.accept(MediaType.APPLICATION_JSON), peopleRepositoryHandler::insertPeople)
.DELETE("/repository/deletePeople/{id}", RequestPredicates.accept(MediaType.APPLICATION_JSON), peopleRepositoryHandler::deletePeople)
.build();
}
@Bean
public RouterFunction<ServerResponse> peopleR2dbcTemplateRoutes() {
return RouterFunctions.route()
.GET("/template/listPeople", RequestPredicates.accept(MediaType.APPLICATION_JSON), peopleR2dbcTemplateHandler::listPeople)
.GET("/template/listPeople/{name}", RequestPredicates.accept(MediaType.APPLICATION_JSON), peopleR2dbcTemplateHandler::findPeopleByUsernameContains)
.GET("/template/getPeople/{id}", RequestPredicates.accept(MediaType.APPLICATION_JSON), peopleR2dbcTemplateHandler::findPeopleById)
.POST("/template/insertPeople", RequestPredicates.accept(MediaType.APPLICATION_JSON), peopleR2dbcTemplateHandler::insertPeople)
.POST("/template/updatePeople", RequestPredicates.accept(MediaType.APPLICATION_JSON), peopleR2dbcTemplateHandler::updatePeople)
.DELETE("/template/deletePeople/{id}", RequestPredicates.accept(MediaType.APPLICATION_JSON), peopleR2dbcTemplateHandler::deletePeople)
.build();
}
}
7、application.properties
server.port=8080
spring.r2dbc.username=root
spring.r2dbc.password=root
spring.r2dbc.url=r2dbc:mysql://localhost:3306/test?characterEncoding=UTF-8&useSSL=false&allowPublicKeyRetrieval=true
spring.r2dbc.pool.enabled=true
logging.level.org.springframework.r2dbc=DEBUG
至此,整合数据库实现增删改查的一个简单响应式编程Web项目就搭建完成。详细的项目目录结构如下图: