欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Kotlin 协程 + Spring webflux 开发后端

程序员文章站 2022-03-26 18:17:12
前言后端响应式是未来,吞吐量会更大,而资源占用更少,其用到了类似Android系统的Loop(事件循环)机制,而协程可以减少线程等待的消耗,并且同步式的编程方式使代码可读性更高,两个仿佛天生就是一对,所以就来简单的了解并配置一下Kotlin 协程 + Spring webflux的后端项目正文项目配置采用Gradle(毕竟我是做Android开发的,所以一切亲Android体系),数据库用的Mysql首先settings.gradle.kts文件,项目名暂定JavaKjrootProj...

前言

后端响应式是未来,吞吐量会更大,而资源占用更少,其用到了类似Android系统的Loop(事件循环)机制,而协程可以减少线程等待的消耗,并且同步式的编程方式使代码可读性更高,两个仿佛天生就是一对,所以就来简单的了解并配置一下Kotlin 协程 + Spring webflux的后端项目

正文

项目配置采用Gradle(毕竟我是做Android开发的,所以一切亲Android体系),数据库用的Mysql

首先settings.gradle.kts文件,项目名暂定JavaKj

rootProject.name = "JavaKj"

然后build.gradle.kts

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
    id("org.springframework.boot") version "2.3.5.RELEASE"
    id("io.spring.dependency-management") version "1.0.10.RELEASE"
    kotlin("jvm") version "1.4.10"
    kotlin("plugin.spring") version "1.4.10"
}

group = "com.lt.javakj"
version = "0.0.1"
java.sourceCompatibility = JavaVersion.VERSION_1_8

repositories {
    mavenCentral()
}

dependencies {
    //测试库
    testImplementation("org.springframework.boot:spring-boot-starter-test") {
        exclude(group = "org.junit.vintage", module = "junit-vintage-engine")
    }
    testImplementation("junit:junit:4.13")
    testImplementation("io.projectreactor:reactor-test")

    //spring webflux 响应式服务端框架,使用方法基本等同spring mvc(除了返回值)
    implementation("org.springframework.boot:spring-boot-starter-webflux")
    //webflux 返回值的协程支持
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor")
    //webflux await的协程支持
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactive")
    //异步数据库支持
    implementation("org.springframework.boot:spring-boot-starter-data-r2dbc")
    //mysql 的异步数据库支持
    implementation("dev.miku:r2dbc-mysql")
    //json解析(默认就是jackson)
    implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
    //webflux kt扩展
    implementation("io.projectreactor.kotlin:reactor-kotlin-extensions")
    //kt反射
    implementation("org.jetbrains.kotlin:kotlin-reflect")
    //kotlin核心库
    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
    //网络请求
    implementation("com.squareup.okhttp3:okhttp:3.14.9")
}

tasks.withType<Test> {
    useJUnitPlatform()
}

tasks.withType<KotlinCompile> {
    kotlinOptions {
        freeCompilerArgs = listOf("-Xjsr305=strict")
        jvmTarget = "1.8"
    }
}

目前项目结构是这样:

Kotlin 协程 + Spring webflux 开发后端

然后打开application.properties文件增加以下配置

#修改端口号
server.port=xxxxx (最好大于一万并小于65535,具体自行搜索)
#
#配置mysql r2dbc
spring.r2dbc.password=mysql密码
spring.r2dbc.username=mysql用户名
spring.r2dbc.url=r2dbcs:mysql://mysqlip:mysql端口/mysql的数据库名

然后spring webflux的操作其他还是跟spring mvc是一样的,这里就不赘述,唯一不同的是返回值

示例controller

import kotlinx.coroutines.reactor.mono
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.data.r2dbc.core.DatabaseClient
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
import reactor.core.publisher.Flux
import reactor.core.publisher.Mono
import javax.annotation.Resource

/**
 * creator: lt  2020/11/11  lt.dygzs@qq.com
 * effect : test的接口
 * warning:
 */
@RestController
@RequestMapping("/api/ad")
class TestInterface {

    @GetMapping("/findAll")
    fun findAll(): Flux<TestBean?> //返回Flux<T>表示是个list

    @GetMapping("/addData")
    fun addData(): Mono<TestBean> //返回Mono<T>表示是单个对象
}

示例数据库表的实体类和数据库操作对象

import org.springframework.data.annotation.Id
import org.springframework.data.relational.core.mapping.Table
import org.springframework.data.repository.kotlin.CoroutineSortingRepository

/**
 * creator: lt  2020/11/11  lt.dygzs@qq.com
 * effect : 表实体类
 * warning:
 */
@Table("feedback")
class TestBean(
        @Id
        var id: Long? = null,//如果id为null,则为自增,并且需要var
        val create_time: Long = 0,
        val content: String? = null,
        val user_id: Long = 0,
        val urls: String? = null,
        val is_solve: Int = 0,
        val solve_time: Long = 0,
)

/**
 * creator: lt  2020/11/11  lt.dygzs@qq.com
 * effect : 数据库操作类
 * warning:
 */
interface TestDB : CoroutineSortingRepository<TestBean, Long>

然后就可以在接口里去增删改查数据了,比如增加一条数据

Kotlin 协程 + Spring webflux 开发后端

其中mono{}是开启了一个以Mono<T>为返回值的协程,而TestDB实现了CoroutineSortingRepository接口,所以其内的大部分方法都是suspend的
这里我们插入一条数据(挂起了),然后打印一下返回值(就是插入的对象),并返回这个对象

这个db提供了如savexxx,findxxx,deletexxxx等简单的操作,如果需要自己执行sql语句,需要如下:

Kotlin 协程 + Spring webflux 开发后端

需要注意的是,如果flux内的suspend lambda走完的话,这个接口就完成了,也就是说如果是在回调中在调用channel.send是无效的,需要改成使用协程的形式

自己执行sql语句还有以下的api:

//查询,返回Flux<T>
databaseClient.execute("select * from client_user").as(ClientUser.class)
                .fetch()
                .all();
//插入,返回Mono<Integer>
databaseClient.insert().into(ClientUser.class)
                .using(clientUser)
                .fetch().rowsUpdated();

然后使用基本就ok了,可以直接运行测试一下

扩展

可能第一次自己写sql没有绑定到数据库表上,如下图,然后我就大概说一下怎么绑定,绑定完就会有sql的代码提示了

Kotlin 协程 + Spring webflux 开发后端

步骤如下:

Kotlin 协程 + Spring webflux 开发后端

Kotlin 协程 + Spring webflux 开发后端

然后如下简单配置一下

Kotlin 协程 + Spring webflux 开发后端

会弹出
Kotlin 协程 + Spring webflux 开发后端

在里面执行一下,然后在同步一下

use 你的数据库名 ;

然后回去

Kotlin 协程 + Spring webflux 开发后端

可以把默认的(所有文件)改成这个库,并把当前文件的私有设置删掉(或者你单独改某文件也行)

Kotlin 协程 + Spring webflux 开发后端

Kotlin 协程 + Spring webflux 开发后端

然后sql语句就有代码提示了

Kotlin 协程 + Spring webflux 开发后端

如果有什么写的不对的请大佬们指出,我用的还不熟练,相当于给自己写了一个文档 \嘿嘿

end

本文地址:https://blog.csdn.net/qq_33505109/article/details/109644018