WebFlux 集成 Thymeleaf 、 Mongodb 实践

  • 时间:
  • 浏览:0
  • 来源:大发快3_快3登录_大发快3登录

这是泥瓦匠的第105篇原创

文章工程:

  • JDK 1.8
  • Maven 3.5.2
  • Spring Boot 2.1.3.RELEASE
  • 工程名:springboot-webflux-5-thymeleaf-mongodb
  • 工程地址:见文末

前言

本小章节,主要还是总结下上面两讲的操作,并实现下复杂性查询的小案例。越来越 没装 MongoDB 的可不上能进行下面的安装流程。

Docker 安装 MognoDB 并启动如下:

1、创建挂载目录

docker volume create mongo_data_db
docker volume create mongo_data_configdb

2、启动 MognoDB

docker run -d \
    --name mongo \
    -v mongo_data_configdb:/data/configdb \
    -v mongo_data_db:/data/db \
    -p 27017:27017 \
    mongo \
    --auth

3、初始化管理员账号

docker exec -it mongo     mongo              admin
                        // 容器名   // mongo命令 数据库名

# 创建最高权限用户
db.createUser({ user: 'admin', pwd: 'admin', roles: [ { role: "root", db: "admin" } ] });

4、测试连通性

docker run -it --rm --link mongo:mongo mongo mongo -u admin -p admin --authenticationDatabase admin mongo/admin

MognoDB 基本操作:

累似 于 MySQL 命令,显示库列表:

show dbs

使用某数据库

use admin

显示表列表

show collections

不可能 所处 city 表,格式化显示 city 表内容

db.city.find().pretty()

不可能 不可能 安装后,就让 我重启即可。

查看已有的镜像

docker images

就让 docker start mogno 即可, mongo 是镜像唯一名词。

行态

累似 于上面讲的工程搭建,新建三个白 工程编写此案例。工程如图:

目录核心如下

  • pom.xml Maven依赖配置
  • application.properties 配置文件,配置 mongo 连接属性配置
  • dao 数据访问层
  • controller 展示层实现

新增 POM 依赖与配置

在 pom.xml 配置新的依赖:

    <!-- Spring Boot 响应式 MongoDB 依赖 -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
    </dependency>

    <!-- 模板引擎 Thymeleaf 依赖 -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>

累似 于配了 MySQL 和 JDBC 驱动,肯定得去配置数据库。在 application.properties 配置下上面启动的 MongoDB 配置:

数据库名为 admin、账号密码也为 admin。

spring.data.mongodb.host=localhost
spring.data.mongodb.database=admin
spring.data.mongodb.port=27017
spring.data.mongodb.username=admin
spring.data.mongodb.password=admin

MongoDB 数据访问层 CityRepository

修改 CityRepository 类,代码如下:

import org.spring.springboot.domain.City;
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface CityRepository extends ReactiveMongoRepository<City, Long> {

    Mono<City> findByCityName(String cityName);

}

CityRepository 接口就让 我继承 ReactiveMongoRepository 类即可。

这里实现了通过城市名找出唯一的城市对象方法:

Mono<City> findByCityName(String cityName);

复杂性查询语录实现也很简单,就让 我依照接口实现规范,即可实现对应 mysql 的 where 查询语录。这里findByxxx ,xxx 可不上能映射任何字段,包括主键等。

接口的命名是遵循规范的。常用命名规则如下:

  • 关键字 :: 方法命名
  • And :: findByNameAndPwd
  • Or :: findByNameOrSex
  • Is :: findById
  • Between :: findByIdBetween
  • Like :: findByNameLike
  • NotLike :: findByNameNotLike
  • OrderBy :: findByIdOrderByXDesc
  • Not :: findByNameNot

除理器类 Handler 和控制器类 Controller

修改下 Handler ,代码如下:

@Component
public class CityHandler {

    private final CityRepository cityRepository;

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

    public Mono<City> save(City city) {
        return cityRepository.save(city);
    }

    public Mono<City> findCityById(Long id) {

        return cityRepository.findById(id);
    }

    public Flux<City> findAllCity() {

        return cityRepository.findAll();
    }

    public Mono<City> modifyCity(City city) {

        return cityRepository.save(city);
    }

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

    public Mono<City> getByCityName(String cityName) {
        return cityRepository.findByCityName(cityName);
    }
}

新增对应的方法,直接返回 Mono 对象,不时要对 Mono 进行转换,不可能 Mono 并不是是个对象,可不上能被 View 层渲染。继续修改下控制器类 Controller ,代码如下:

    @Autowired
    private CityHandler cityHandler;

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

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

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

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

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

    private static final String CITY_LIST_PATH_NAME = "cityList";
    private static final String CITY_PATH_NAME = "city";

    @GetMapping("/page/list")
    public String listPage(final Model model) {
        final Flux<City> cityFluxList = cityHandler.findAllCity();
        model.addAttribute("cityList", cityFluxList);
        return CITY_LIST_PATH_NAME;
    }

    @GetMapping("/getByName")
    public String getByCityName(final Model model,
                                @RequestParam("cityName") String cityName) {
        final Mono<City> city = cityHandler.getByCityName(cityName);
        model.addAttribute("city", city);
        return CITY_PATH_NAME;
    }

新增 getByName 路径,指向了新的页面 city。使用 @RequestParam 接受 GET 请求入参,接受的参数为 cityName ,城市名称。视图返回值 Mono 不可能 String 都行。

Tymeleaf 视图

就让 编写三个白 视图 city 和 cityList,代码分别如下:

city.html:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8"/>
    <title>城市</title>
</head>

<body>

<div>


    <table>
        <legend>
            <strong>城市单个查询</strong>
        </legend>
        <tbody>
            <td th:text="${city.id}"></td>
            <td th:text="${city.provinceId}"></td>
            <td th:text="${city.cityName}"></td>
            <td th:text="${city.description}"></td>
        </tbody>
    </table>

</div>

</body>
</html>

cityList.html:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8"/>
    <title>城市列表</title>
</head>

<body>

<div>


    <table>
        <legend>
            <strong>城市列表</strong>
        </legend>
        <thead>
        <tr>
            <th>城市编号</th>
            <th>省份编号</th>
            <th>名称</th>
            <th>描述</th>
        </tr>
        </thead>
        <tbody>
        <tr th:each="city : ${cityList}">
            <td th:text="${city.id}"></td>
            <td th:text="${city.provinceId}"></td>
            <td th:text="${city.cityName}"></td>
            <td th:text="${city.description}"></td>
        </tr>
        </tbody>
    </table>

</div>

</body>
</html>

运行工程

三个白 CRUD 的 Spring Boot Webflux 工程就开发完毕了,下面运行工程验证下。使用 IDEA 右侧工具栏,点击 Maven Project Tab ,点击使用下 Maven 插件的 install 命令。不可能 使用命令行的形式,在工程根目录下,执行 Maven 清理和安装工程的指令:

cd springboot-webflux-5-thymeleaf-mongodb
mvn clean install

在控制台中看了成功的输出:

... 省略
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 01:100 min
[INFO] Finished at: 2017-10-15T10:00:54+08:00
[INFO] Final Memory: 31M/174M
[INFO] ------------------------------------------------------------------------

在 IDEA 中执行 Application 类启动,任意正常模式不可能 Debug 模式。可不上能在控制台看了成功运行的输出:

... 省略
2018-04-10 08:43:39.932  INFO 2052 --- [ctor-http-nio-1] r.ipc.netty.tcp.BlockingNettyContext     : Started HttpServer on /0:0:0:0:0:0:0:0:100100
2018-04-10 08:43:39.935  INFO 2052 --- [           main] o.s.b.web.embedded.netty.NettyWebServer  : Netty started on port(s): 100100
2018-04-10 08:43:39.9100  INFO 2052 --- [           main] org.spring.springboot.Application        : Started Application in 6.547 seconds (JVM running for 9.851)

打开 POST MAN 工具,开发必备。进行下面操作:

新增城市信息 POST http://127.0.0.1:100100/city

打开浏览器,访问 http://localhost:100100/city/getByName?cityName=杭州,可不上能看了如图的响应:

继续访问 http://localhost:100100/city/page/list , 发现越来越 值,越来越 按照上一讲插入几只数据即可有值,如图:

总结

这里,初步实现了三个白 简单的整合,具体复杂性的案例一些人在综合案例中实现,会很酷炫很适合。下面整合 Redis ,基于 Redis 可不上能实现常用的 缓存、锁 ,下一讲,一些人学习下如可整合 Reids 吧。

源代码地址:https://github.com/JeffLi1993/springboot-learning-example

系列教程目录

  • 《01:WebFlux 系列教程大纲》

  • 《02:WebFlux 快速入门实践》
  • 《03:WebFlux Web CRUD 实践》

  • 《04:WebFlux 整合 Mongodb》
  • 《05:WebFlux 整合 Thymeleaf》
  • 《06:WebFlux 中 Thymeleaf 和 Mongodb 实践》
  • 《07:WebFlux 整合 Redis》

  • 《08:WebFlux 中 Redis 实现缓存》
  • 《09:WebFlux 中 WebSocket 实现通信》
  • 《10:WebFlux 集成测试及部署》
  • 《11:WebFlux 实战图书管理系统》

代码示例

本文示例读者可不上能通过查看下面仓库的中的模块工程名: 2-x-spring-boot-webflux-handling-errors:

  • Github:https://github.com/JeffLi1993/springboot-learning-example
  • Gitee:https://gitee.com/jeff1993/springboot-learning-example

不可能 您对哪此感兴趣,欢迎 star、follow、收藏、转发给予支持!

参考资料

  • Spring Boot 2.x WebFlux 系列:https://www.bysocket.com/archives/2290
  • spring.io 官方文档