专栏首页CodeSheep的技术分享初探Kotlin+SpringBoot联合编程
原创

初探Kotlin+SpringBoot联合编程

Macbook

Kotlin是一门最近比较流行的静态类型编程语言,而且和Groovy、Scala一样同属Java系。Kotlin具有的很多静态语言特性诸如:类型判断、多范式、扩展函数、模式匹配等等让我无法只作为一个吃瓜群众了,所以稍微花了点时间了解了一下该语言。

本文主要介绍一下如何使用Kotlin结合SpringBt开发一个带有数据库交互的REST风格基本程序


实验环境

  • JDK不用说了,Kotlin毕竟是运行在JVM环境下的语言,所以JDK必须,我这里用的JDK1.8
  • 数据库:MySQL
  • 数据库访问组件:Spring data jpa
  • J2EE框架:SpringBt 1.5.2.RELEASE
  • 构建工具:Gradle

工程创建

没啥好说的,我这里创建的是基于Gradle的Kotlin工程:

基于Gradle的Kotlin工程

创建完成后的基本工程样式和SpringBt的工程几乎没任何区别,给张图示意一下好了:

工程基本样式

好啦,接下来我们就来写代码完善这个工程即可


完善build.gradle配置

我们需要在build.gradle中引入SpringBt依赖,除此之外还要引入一些特定的插件方便我们向写Java代码一样来写Kotlin程序!

在dependencies中加入如下依赖:

dependencies {
    compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version"
    testCompile group: 'junit', name: 'junit', version: '4.12'
    compile("org.springframework.boot:spring-boot-starter-web")
    testCompile("org.springframework.boot:spring-boot-starter-test")
    compile("org.springframework.boot:spring-boot-starter-data-jpa")
    compile('mysql:mysql-connector-java:5.1.13')
}

这样SpringBt相关的依赖就配置上了!

接下来我们配置两个非常关键的插件依赖:

  • 无参(no-arg)插件
  • 全开放(allopen)插件

我们先配上,等下解释:

buildscript {
    ext.kotlin_version = '1.1.1'
    ext.springboot_version = '1.5.2.RELEASE'

    repositories {
        mavenCentral()
    }
    dependencies {
        // Kotlin Gradle插件
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        // SpringBoot Gradle插件
        classpath("org.springframework.boot:spring-boot-gradle-plugin:$springboot_version")
        // Kotlin整合SpringBoot的默认无参构造函数,默认把所有的类设置open类插件
        classpath("org.jetbrains.kotlin:kotlin-noarg:$kotlin_version") // 无参插件
        classpath("org.jetbrains.kotlin:kotlin-allopen:$kotlin_version") // 全开放插件
    }
}

其中(以下解释源自《Kotlin极简教程》):

  • org.jetbrains.kotlin:kotlin-noarg是无参(no-arg)编译器插件,它为具有特定注解的类生成一个额外的零参数构造函数。 这个生成的构造函数是合成的,因此不能从 Java 或 Kotlin 中直接调用,但可以使用反射调用。 这样我们就可以使用 Java Persistence API(JPA)实例化 data 类。
  • org.jetbrains.kotlin:kotlin-allopen 是全开放编译器插件。我们使用Kotlin 调用Java的Spring AOP框架和库,需要类为 open(可被继承实现),而Kotlin 类和函数都是默认 final 的,这样我们需要为每个类和函数前面加上open修饰符。这样的代码写起来很费事。还好,我们有all-open 编译器插件。它会适配 Kotlin 以满足这些框架的需求,并使用指定的注解标注类而其成员无需显式使用 open 关键字打开。 例如,当我们使用 Spring 时,就不需要打开所有的类,跟我们在Java中写代码一样,只需要用相应的注解标注即可,如 @Configuration 或 @Service。

讲白了,引入这两个特定的插件的目的就是为了方便我们向写SpringBt代码一样来写Kotlin程序!


配置application.properties

这里面主要是跟Mysql数据库相关的一些配置:

spring.datasource.url = jdbc:mysql://localhost:3306/easykotlin
spring.datasource.username = root
spring.datasource.password = 你的Mysql密码
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.database = MYSQL
spring.datasource.testWhileIdle = true
spring.datasource.validationQuery = SELECT 1
spring.jpa.show-sql = true
spring.jpa.hibernate.ddl-auto = update
spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect

server.port=7000

正式编写工程

我们需要去数据库中查询东西,所以二话不说,写个访问数据库的标准代码层:

  • controller
  • entity
  • repository
  • service
整体代码框架

各部分代码如下:

  • People.kt
@Entity
class People(
        @Id @GeneratedValue(strategy = GenerationType.AUTO)
        val id: Long?,
        val firstName: String?,
        val lastName: String?,
        val gender: String?,
        val age: Int?,
        val gmtCreated: Date,
        val gmtModified: Date
) {
    override fun toString(): String {
        return "People(id=$id, firstName='$firstName', lastName='$lastName', gender='$gender', age=$age, gmtCreated=$gmtCreated, gmtModified=$gmtModified)"
    }
}
  • PeopleRepository.kt
interface PeopleRepository : CrudRepository<People, Long> {
    fun findByLastName(lastName: String): List<People>?
}
  • PeopleService.kt
@Service
class PeopleService : PeopleRepository {

    @Autowired
    val peopleRepository: PeopleRepository? = null

    override fun findByLastName(lastName: String): List<People>? {
        return peopleRepository?.findByLastName(lastName)
    }

    override fun <S : People?> save(entity: S): S? {
        return peopleRepository?.save(entity)
    }

    override fun <S : People?> save(entities: MutableIterable<S>?): MutableIterable<S>? {
        return peopleRepository?.save(entities)
    }

    override fun delete(entities: MutableIterable<People>?) {
    }

    override fun delete(entity: People?) {
    }

    override fun delete(id: Long?) {
    }

    override fun findAll(ids: MutableIterable<Long>?): MutableIterable<People>? {
        return peopleRepository?.findAll(ids)
    }

    override fun findAll(): MutableIterable<People>? {
        return peopleRepository?.findAll()
    }

    override fun exists(id: Long?): Boolean {
        return peopleRepository?.exists(id)!!
    }

    override fun count(): Long {
        return peopleRepository?.count()!!
    }

    override fun findOne(id: Long?): People? {
        return peopleRepository?.findOne(id)
    }

    override fun deleteAll() {
    }
}
  • PeopleController.kt
@Controller
class PeopleController {
    @Autowired
    val peopleService: PeopleService? = null

    @GetMapping(value = "/hello")
    @ResponseBody
    fun hello(@RequestParam(value = "lastName") lastName: String): Any {
        val peoples = peopleService?.findByLastName(lastName)
        val map = HashMap<Any, Any>()
        map.put("hello", peoples!!)
        return map
    }
}

可见有了无参、全开放组件加持后,写代码和写Java的代码基本没区别了


实际实验

首先需要去Mysql中建好数据库,并插入一些数据:

数据库预览

然后启动工程,访问:

http://localhost:7000/hello?lastName=wang

可以看到数据成功被取回:

成功获取到数据

参考文献

《Kotlin极简教程》


后记

作者更多的原创文章在云加社区

作者更多的SpringBt实践文章在此:


CodeSheep

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Elastic Search搜索引擎在SpringBoot中的实践

    CodeSheep
  • 初探Kotlin+SpringBoot联合编程

    CodeSheep
  • SpringBoot应用Docker化

    CodeSheep
  • Socket学习总结系列(一) -- IM & Socket

    Socket通讯在iOS中也是很常见,自己最近也一直在学习Telegram这个开源项目,Telegram就是在Socket的基础上做的即时通讯,这个相信了解这...

    Mr.RisingSun
  • Spring Boot + Spring Cloud 构建微服务系统(九):配置中心(Spring Cloud Config)

    如今微服务架构盛行,在分布式系统中,项目日益庞大,子项目日益增多,每个项目都散落着各种配置文件,且随着服务的增加而不断增多。此时,往往某一个基础服务信息变更,都...

    朝雨忆轻尘
  • 请尊重别人的劳动成果

    我已经很多次看到别人转载我的文章但是没有标注出处的,但起码有转载类似的字样,但下面这位貌似有点过份了:

    IT晴天
  • SpringCloud配置中心客户端读取配置

    微服务连接配置中心来实现外部配置的读取。 引入依赖 <dependencies> <dependency> <groupId>org.s...

    Java技术栈
  • Windows Phone SDK 7.1 中文版本发布

            自2011年9月底推出Windows Phone SDK 7.1 RTM版本之后,很多国内的开发者焦急地等待着中文版本的推出。因为很多装了...

    ShiJiong
  • springcloud(八):配置中心服务化和高可用

    在前两篇的介绍中,客户端都是直接调用配置中心的server端来获取配置文件信息。这样就存在了一个问题,客户端和服务端的耦合性太高,如果server端要做集群,客...

    纯洁的微笑
  • 我们自研的那些Devops工具

    2018年为了解决日常运维中的痛点以及更高效的推进运维工作,我们自研并完善了几个工具系统,这些系统无一例外的帮我们节约了时间,提高了效率,这篇文章将分享介绍一下...

    37丫37

扫码关注云+社区

领取腾讯云代金券