这是泥瓦匠的第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:30 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:8080
2018-04-10 08:43:39.935 INFO 2052 --- [ main] o.s.b.web.embedded.netty.NettyWebServer : Netty started on port(s): 8080
2018-04-10 08:43:39.960 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:8080/city

打开浏览器,访问 http://localhost:8080/city/getByName?cityName=杭州,可以看到如图的响应:

继续访问 http://localhost:8080/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:

如果您对这些感兴趣,欢迎 star、follow、收藏、转发给予支持!

参考资料

WebFlux 集成 Thymeleaf 、 Mongodb 实践 - Spring Boot(六)的更多相关文章

  1. 《深入实践Spring Boot》阅读笔记之一:基础应用开发

    上上篇「1718总结与计划」中提到,18年要对部分项目拆分,进行服务化,并对代码进行重构.公司技术委员会也推荐使用spring boot,之前在各个技术网站中也了解过,它可以大大简化spring配置和 ...

  2. 《深入实践Spring Boot》阅读笔记之二:分布式应用开发

    上篇文章总结了<深入实践Spring Boot>的第一部分,这篇文章介绍第二部分:分布式应用开发,以及怎么构建一个高性能的服务平台. 主要从以下几个方面总结: Spring Boot SS ...

  3. 《深入实践Spring Boot》阅读笔记之三:核心技术源代码分析

    刚关注的朋友,可以回顾前两篇文章: 基础应用开发 分布式应用开发 上篇文章总结了<深入实践Spring Boot>的第二部分,本篇文章总结第三部分,也是最后一部分.这部分主要讲解核心技术的 ...

  4. Spring Boot(六):如何使用mybatis

    Spring Boot(六):如何使用mybatis orm框架的本质是简化编程中操作数据库的编码,发展到现在基本上就剩两家了,一个是宣称可以不用写一句SQL的hibernate,一个是可以灵活调试动 ...

  5. Spring Boot 2 快速教程:WebFlux 集成 Thymeleaf(五)

    号外:为读者持续整理了几份最新教程,覆盖了 Spring Boot.Spring Cloud.微服务架构等PDF.获取方式:关注右侧公众号"泥瓦匠BYSocket",来领取吧! 摘 ...

  6. Spring Boot实践——Spring Boot 2.0 新特性和发展方向

    出自:https://mp.weixin.qq.com/s/EWmuzsgHueHcSB0WH-3AQw 以Java 8 为基准 Spring Boot 2.0 要求Java 版本必须8以上, Jav ...

  7. 后端开发实践——Spring Boot项目模板

    在我的工作中,我从零开始搭建了不少软件项目,其中包含了基础代码框架和持续集成基础设施等,这些内容在敏捷开发中通常被称为"第0个迭代"要做的事情.但是,当项目运行了一段时间之后再来反 ...

  8. Thymeleaf 模板 在spring boot 中的引用和应用

    Thymeleaf是一个java类库,他是一个xml/xhtml/html5的模板引擎和Struts框架的freemarker模板类似,可以作为mvc的web应用的view层. Thymeleaf还提 ...

  9. 使用MongoDB的Spring Boot和MongoTemplate教程

    在本教程中,我们将构建一个Spring Boot应用程序,该应用程序演示如何使用MongoTemplate API访问MongoDB数据库中的数据. 对于MongoDB,我们将使用mLab,它提供了M ...

随机推荐

  1. 将 WPF、UWP 以及其他各种类型的旧 csproj 迁移成基于 Microsoft.NET.Sdk 的新 csproj

    原文 将 WPF.UWP 以及其他各种类型的旧 csproj 迁移成基于 Microsoft.NET.Sdk 的新 csproj 写过 .NET Standard 类库或者 .NET Core 程序的 ...

  2. 创建asp.net core 的静态网站

    这个名字听起来很怪 既然是静态网站 为什么要是asp.net core的呢? 1.在vs上面好像不能创建纯静态的网站,所以我们就想创建一个asp.net core的空网站 然后在里面使用静态的html ...

  3. 随机森林与 GBDT

    随机森林(random forest),GBDT(Gradient Boosting Decision Tree),前者中的森林,与后者中的 Boosting 都在说明,两种模型其实都是一种集成学习( ...

  4. Leetcode 169 Majority Element 分治

    在一个长度为n的数组中找出出现次数超过(n+1)/2次的数 说明请参考编程之美中的2.3 class Solution { public: int majorityElement(vector< ...

  5. 【甘道夫】基于Mahout0.9+CDH5.2执行分布式ItemCF推荐算法

    环境: hadoop-2.5.0-cdh5.2.0 mahout-0.9-cdh5.2.0 引言 尽管Mahout已经宣布不再继续基于Mapreduce开发,迁移到Spark.可是实际面临的情况是公司 ...

  6. FastDFS是纯C语言实现,只支持Linux,适合以中小文件为载体的在线服务,还可以冗余备份和负载均衡

    一.理论基础 FastDFS比较适合以中小文件为载体的在线服务,比如跟NGINX(APACHE)配合搭建图片服务器. 分布式文件系统FastDFS FastDFS是纯C语言实现,只支持Linux.Fr ...

  7. 整型转字符串(convert int to char)优化实践——一个意外的BUG

    convert_int_to_char函数在使用时出现过一个BUG. 当使用值是13200020099时,返回的字符串是"13200020111",结果是错误的. 在gcc编译器里 ...

  8. 【LeetCode】LRU Cache 解决报告

    插话:只写了几个连续的博客,博客排名不再是实际"远在千里之外"该.我们已经进入2一万内. 再接再厉.油! Design and implement a data structure ...

  9. WPF中的 Layout To Layout

    原文:WPF中的 Layout To Layout   WPF中的 Layout To Layout                             周银辉 WPF的布局功能异常强大,当有时我 ...

  10. [转载]Delphi常用类型及定义单元

    原文地址:Delphi常用类型及定义单元作者:沧海一声笑 Delphi常用类型及定义单元-总结  sndplaysound                mmsystem Type Unit Date ...