使用Kotlin开发Webflux应用
使用技术。kotlin,gradle,SpringBoot2.0,WebFlux,Mybatis,Thymeleaf
技术介绍
Kotlin** 是一种在 Java 虚拟机上运行的静态类型编程语言,被称之为 Android 世界的Swift,由 JetBrains 设计开发并开源。
Kotlin 可以编译成Java字节码,也可以编译成 JavaScript,方便在没有 JVM 的设备上运行。
在Google I/O 2017中,Google 宣布 Kotlin 成为 Android 官方开发语言。
而Spring5之后,大部分Spring系框架也支持了kotlin。
Gradle是一个基于Apache Ant和Apache Maven概念的项目自动化构建开源工具。它使用一种基于Groovy的特定领域语言(DSL)来声明项目设置,抛弃了基于XML的各种繁琐配置。面向Java应用为主。当前其支持的语言限于Java、Groovy、Kotlin和Scala,计划未来将支持更多的语言。
Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。通过这种方式,Spring Boot致力于在蓬勃发展的快速应用开发领域(rapid application development)成为领导者。
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。
WebFlux 模块的名称是 spring-webflux,名称中的 Flux 来源于 Reactor 中的类 Flux。该模块中包含了对反应式 HTTP、服务器推送事件和 WebSocket 的客户端和服务器端的支持。对于开发人员来说,比较重要的是服务器端的开发,这也是本文的重点。在服务器端,WebFlux 支持两种不同的编程模型:第一种是 Spring MVC 中使用的基于 Java 注解的方式;第二种是基于 Java 8 的 lambda 表达式的函数式编程模型。这两种编程模型只是在代码编写方式上存在不同。它们运行在同样的反应式底层架构之上,因此在运行时是相同的。WebFlux 需要底层提供运行时的支持,WebFlux 可以运行在支持 Servlet 3.1 非阻塞 IO API 的 Servlet 容器上,或是其他异步运行时环境,如 Netty 和 Undertow。
Thymeleaf是用于Web和独立环境的现代服务器端Java模板引擎。Thymeleaf的主要目标是将优雅的自然模板带到您的开发工作流程中—HTML能够在浏览器中正确显示,并且可以作为静态原型,从而在开发团队中实现更强大的协作。Thymeleaf能够处理HTML,XML,JavaScript,CSS甚至纯文本。Thymeleaf的主要目标是提供一个优雅和高度可维护的创建模板的方式。 为了实现这一点,它建立在自然模板的概念之上,以不影响模板作为设计原型的方式将其逻辑注入到模板文件中。 这改善了设计沟通,弥合了前端设计和开发人员之间的理解偏差。Thymeleaf也是从一开始就设计(特别是HTML5)允许创建完全验证的模板。
创建
创建项目,使用Spring工具创建 网址 https://start.spring.io/
注意构建工具,语言,引入依赖
点击>构建项目
解压压缩包。将内容放到项目目录。使用IDEA打开这个项目。
整理项目
将包名整理一下,构建工具将会把项目名也构建到包中,需要删除。
配置
application.yml
server:
port: 3011
mybatis:
mapperLocations: classpath:mapper/*.xml
logging:
level:
root: debug
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
password: 123456
url: jdbc:mysql://localhost:3306/webflux_demo?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true
username: root
hikari:
driver-class-name: com.mysql.cj.jdbc.Driver
maximum-pool-size: 30
日志请调制Debug,因为异常运行异常只有在Debug才能看到
创建CityEntiy.kt
data class CityEntity(var id: Long?=0L,
var name: String = "",
var privinceId: Long = 0L,
var description:String ="")
kotlin有一个data修饰符,修饰class,这个类将会变成实体类,自动生成get,set。
创建CityDao.kt
@Mapper
interface CityDao {
@Select("select id,name,privince_id,description from city ")
fun findAll(): List<CityEntity>
@Select("insert into city (name,privince_id,description ) values (#{name},#{privince_id},#{description})")
fun insert(entity: CityEntity): Int
}
这里比较简单,使用了Select注解,没有使用xml。
创建CityService.kt
@Service
class CityService {
@Autowired
private lateinit var cityDao:CityDao
fun getAll(): Flux<CityEntity> {
var list=cityDao.findAll()
//此处应该使用流处理,但是不知道为什么一直报错
/**
*
val flux = Flux.push<CityEntity> { fluxSink ->
list.stream().collect(data->{fluxSink.next(data) })
fluxSink.complete()
}
*/
val flux = Flux.push<CityEntity> { fluxSink ->
for (entity in list) {
fluxSink.next(entity);
}
fluxSink.complete()
}
return flux
}
}
创建CityController
@Controller
@RequestMapping("/")
class CityController {
@Autowired
private lateinit var cityService: CityService
@GetMapping()
fun getAll(model:Model): Mono<String> {
var list=cityService.getAll()
model.addAttribute("list",list)
return Mono.create { monoSink -> monoSink.success("cityList") }
}
}
创建cityList.html
<!DOCTYPE html>
<html lang="zh-CN" xmlns:th="http://www.w3.org/1999/xhtml">
<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 : ${list}">
<td th:text="${city.id}"></td>
<td th:text="${city.privinceId}"></td>
<td th:text="${city.name}"></td>
<td th:text="${city.description}"></td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
创建数据库和表
create database webflux_demo;
创建表
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
CREATE TABLE `city` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`privince_id` int(11) NULL DEFAULT NULL,
`description` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
INSERT INTO `city`(name,privince_id,description ) VALUES ( '河南', 0, '河南省');
运行
Github地址
坑
mybatis的entity必须有无参构造函数
如果发现没有无参构造函数,将会报错
所以在data class中,所有的变量都需要有默认值。
共同学习,写下你的评论
评论加载中...
作者其他优质文章