javascript
Kotlin 协程 + Spring webflux 开发后端
前言
后端響應式是未來,吞吐量會更大,而資源占用更少,其用到了類似Android系統的Loop(事件循環)機制,而協程可以減少線程等待的消耗,并且同步式的編程方式使代碼可讀性更高,兩個仿佛天生就是一對,所以就來簡單的了解并配置一下Kotlin 協程 + Spring webflux的后端項目
正文
項目配置采用Gradle(畢竟我是做Android開發的,所以一切親Android體系),數據庫用的Mysql
build.gradle.kts
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" }dependencies {//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") }...目前項目結構是這樣:
然后打開application.properties文件增加以下配置
#修改端口號 server.port=xxxxx (最好大于一萬并小于65535,具體自行搜索) # #配置mysql r2dbc spring.r2dbc.password=mysql密碼 spring.r2dbc.username=mysql用戶名 spring.r2dbc.url=r2dbcs:mysql://mysql的ip: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(@Idvar id: Long? = null,//如果id為null,則為自增,并且需要varval 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>然后就可以在接口里去增刪改查數據了,比如增加一條數據
或者直接聲明掛起函數,如下(聲明等同于上面的方法)
其中mono{}是開啟了一個以Mono<T>為返回值的協程,而TestDB實現了CoroutineSortingRepository接口,所以其內的大部分方法都是suspend的
這里我們插入一條數據(掛起了),然后打印一下返回值(就是插入的對象),并返回這個對象
這個db提供了如savexxx,findxxx,deletexxxx等簡單的操作,如果需要自己執行sql語句,需要如下:
需要注意的是,如果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();?返回Flux也可以這樣寫
或者也可以這樣自定義使用sql,參考:?https://docs.spring.io/spring-framework/docs/current/reference/html/languages.html? ?1.8.2
interface TestDB : CoroutineSortingRepository<TestBean, Long> {@Query("select * from feedback")fun getAll(): Flux<TestBean>@Query("select * from feedback where id = :id")suspend fun get(id: Long): TestBean@Query("select * from feedback where id = 1")fun get2(): Mono<TestBean>suspend fun getById(id: Long): TestBean }api參考:?https://docs.spring.io/spring-data/jpa/docs/2.4.7/reference/html/#reference? 6.3?
然后使用基本就ok了,可以直接運行測試一下
擴展
1.可能你需要java和kt代碼混寫,但用的是gradle,可能會不去編譯java代碼,導致出現NoClassDefFoundError
此時只需要在項目的build.gradle.kts中的最外層添加如下代碼即可,原因是java代碼不知道代碼入口了
sourceSets {main {java.srcDirs("src/main/kotlin")} }2.可能第一次自己寫sql沒有綁定到數據庫表上,如下圖,然后我就大概說一下怎么綁定,綁定完就會有sql的代碼提示了
步驟如下:
然后如下簡單配置一下
會彈出
在里面執行一下,然后在同步一下
use 你的數據庫名 ;然后回去
可以把默認的(所有文件)改成這個庫,并把當前文件的私有設置刪掉(或者你單獨改某文件也行)
然后sql語句就有代碼提示了
如果有什么寫的不對的請大佬們指出,我用的還不熟練,相當于給自己寫了一個文檔 \嘿嘿
end
總結
以上是生活随笔為你收集整理的Kotlin 协程 + Spring webflux 开发后端的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用Retrofit时,对参数进行加密
- 下一篇: 数据结构特性解析 (四)LinkedLi