SpringBootWebFlux学习笔记(三)--CRUD 实践

需求

对城市(City)进行管理实现 CRUD 操作。

项目结构

├── pom.xml
├── src
│    └── main
│        ├── java
│        │     └── org
│        │         └── spring
│        │             └── springboot
│        │                 ├── Application.java
│        │                 ├── dao
│        │                 │    └── CityRepository.java
│        │                 ├── domain
│        │                 │    └── City.java
│        │                 ├── handler
│        │                 │    └── CityHandler.java
│        │                 └── webflux
│        │                     └── controller
│        │                         └── CityWebFluxController.java
│        └── resources
│            └── application.properties
└── target

项目详情

对象

/**
 * 城市实体类
 *
 */
public class City {

    /**
     * 城市编号
     */
    private Long id;

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

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

	// Getter and Setter
}

数据访问层

@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;
    }
}

@Repository 用于标注数据访问组件,即 DAO 组件。实现代码中使用名为 repository 的 Map 对象作为内存数据存储,并对对象具体实现了具体业务逻辑。

处理器类

编写城市处理器类 CityHandler。代码如下:

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

@Component
public class CityHandler {

    private final CityRepository cityRepository;

    @Autowired
    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)));
    }
}

从返回值可以看出,Mono 和 Flux 适用于两个场景,即:

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

Mono & Flux

特性 Mono Flux
元素数量 0 或 1 个元素 0 到 N 个元素
用例 单一结果、可选值 流式数据、多项结果
背景用途 单次请求响应、数据库单记录查询 数据流处理、实时事件流

控制器类

import org.spring.springboot.domain.City;
import org.spring.springboot.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;

@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);
    }
}

启动运行项目

mvn clean install
mvn springboot:run

测试项目

posted @ 2024-10-25 21:15  Jacob-Chen  阅读(21)  评论(0)    收藏  举报