WebFlux02 SpringBoot WebFlux实现CRUD

Posted 寻渝记

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WebFlux02 SpringBoot WebFlux实现CRUD相关的知识,希望对你有一定的参考价值。

1 准备

  基于SpringBoot2.0搭建WebFlux项目,详情请参见三少另外一篇博文

 

2 工程结构

  

<?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>

    <groupId>cn.xiangxu</groupId>
    <artifactId>springboot-webflux-2-crud</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>springboot-webflux-2-crud</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.0</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.projectreactor</groupId>
            <artifactId>reactor-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <fork>true</fork>
                </configuration>
            </plugin>
        </plugins>
    </build>


</project>
pom.xml

  2.1 创建实体类

package cn.xiangxu.springbootwebflux2crud.domain;

import lombok.Data;

/**
 * @author 王杨帅
 * @create 2018-06-21 10:42
 * @desc 城市实体类
 **/
@Data
public class City {
    /**
     * 城市编号
     */
    private Long id;

    /**
     * 省份编号
     */
    private Long provinceId;

    /**
     * 城市名称
     */
    private String cityName;

    /**
     * 描述
     */
    private String description;


}
City.java

  2.2 创建持久层类

    技巧01:本博文利用一个 Map 容器来存储数据

package cn.xiangxu.springbootwebflux2crud.dao;

import cn.xiangxu.springbootwebflux2crud.domain.City;
import org.springframework.stereotype.Repository;

import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicLong;

/**
 * @author 王杨帅
 * @create 2018-06-21 10:54
 * @desc 城市持久层
 **/
@Repository
public class CityRepository {
    private ConcurrentMap<Long, City> repository = new ConcurrentHashMap<>();

    private static final AtomicLong idGenerator = new AtomicLong(0);

    public Long save(City city) {
        Long id = idGenerator.incrementAndGet();
        city.setId(id);
        repository.put(id, city);
        return id;
    }

    public Collection<City> findAll() {
        return repository.values();
    }


    public City findCityById(Long id) {
        return repository.get(id);
    }

    public Long updateCity(City city) {
        repository.put(city.getId(), city);
        return city.getId();
    }

    public Long deleteCity(Long id) {
        repository.remove(id);
        return id;

    }

}
CityRepository.java

  2.3 创建服务层【处理器类】

    技巧01:在 SpringBoot WebFlux 中返回的数据类型是 Mono 或者 Flux 类型

    技巧02:依赖注入时使用的是构造器注入,目的是为了减少和spring的耦合

package cn.xiangxu.springbootwebflux2crud.handler;

import cn.xiangxu.springbootwebflux2crud.dao.CityRepository;
import cn.xiangxu.springbootwebflux2crud.domain.City;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

/**
 * @author 王杨帅
 * @create 2018-06-21 11:08
 * @desc 城市处理器类
 **/
@Component
public class CityHandler {
    private final CityRepository cityRepository;

    public CityHandler(CityRepository cityRepository) {
        this.cityRepository = cityRepository;
    }

    public Mono<Long> save(City city) {
        return Mono.create(cityMonoSink -> cityMonoSink.success(cityRepository.save(city)));
    }

    public Mono<City> findCityById(Long id) {
        return Mono.justOrEmpty(cityRepository.findCityById(id));
    }

    public Flux<City> findAllCity() {
        return Flux.fromIterable(cityRepository.findAll());
    }

    public Mono<Long> modifyCity(City city) {
        return Mono.create(cityMonoSink -> cityMonoSink.success(cityRepository.updateCity(city)));
    }

    public Mono<Long> deleteCity(Long id) {
        return Mono.create(cityMonoSink -> cityMonoSink.success(cityRepository.deleteCity(id)));
    }
}
CityHandler.java

  2.4 创建控制层

    技巧01:和SpringMVC的套路一样

package cn.xiangxu.springbootwebflux2crud.controller;

import cn.xiangxu.springbootwebflux2crud.domain.City;
import cn.xiangxu.springbootwebflux2crud.handler.CityHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

/**
 * @author 王杨帅
 * @create 2018-06-21 11:10
 * @desc 城市控制类
 **/
@RestController
@RequestMapping(value = "/city")
public class CityWebFluxController {
    @Autowired
    private CityHandler cityHandler;

    @GetMapping(value = "/{id}")
    public Mono<City> findCityById(@PathVariable("id") Long id) {
        return cityHandler.findCityById(id);
    }

    @GetMapping()
    public Flux<City> findAllCity() {
        return cityHandler.findAllCity();
    }

    @PostMapping()
    public Mono<Long> saveCity(@RequestBody City city) {
        return cityHandler.save(city);
    }

    @PutMapping()
    public Mono<Long> modifyCity(@RequestBody City city) {
        return cityHandler.modifyCity(city);
    }

    @DeleteMapping(value = "/{id}")
    public Mono<Long> deleteCity(@PathVariable("id") Long id) {
        return cityHandler.deleteCity(id);
    }
}
CityWebFluxController.java

 

3 Mono

  • Mono:实现发布者,并返回 0 或 1 个元素,即单对象。

4 Flux

  • Flux:实现发布者,并返回 N 个元素,即 List 列表对象。

 

以上是关于WebFlux02 SpringBoot WebFlux实现CRUD的主要内容,如果未能解决你的问题,请参考以下文章

WebFlux02 SpringBoot WebFlux实现CRUD

WebFlux 操作 MySQL 是种什么体验?

WebFlux 操作 MySQL 是种什么体验?

SpringBoot2 + Webflux - WebTestClient 总是返回“401 UNAUTHORIZED”

Spring WebFlux添加WebFIlter以匹配特定路径

为啥在 webflux 中使用 WebFilter corsFilter 时请求返回 404 状态?