詳解用Kotlin寫一個(gè)基于Spring Boot的RESTful服務(wù)
Spring太復(fù)雜了,配置這個(gè)東西簡(jiǎn)直就是浪費(fèi)生命。尤其在沒(méi)有什么并發(fā)壓力,隨便搞一個(gè)RESTful服務(wù),讓整個(gè)業(yè)務(wù)跑起來(lái)先的情況下,更是么有必要糾結(jié)在一堆的XML配置上。顯然這么想的人是很多的,于是就有了Spring Boot。又由于Java 8太墨跡于是有了Kotlin。
數(shù)據(jù)源使用MySql。通過(guò)Spring Boot這個(gè)基本不怎么配置的,不怎么微的微框架的Spring Data JPA和Hibernate來(lái)訪問(wèn)數(shù)據(jù)。
處理依賴
這里使用Gradle來(lái)處理依賴。
首先下載官網(wǎng)給的初始項(xiàng)目:
git clone https://github.com/spring-guides/gs-accessing-data-jpa.git
然后跳轉(zhuǎn)到gs-accessing-data-jpa/initial
目錄下。
用IntelliJ IDEA打開(kāi)這個(gè)項(xiàng)目,選擇使用Gradle管理依賴。
之后Gradle會(huì)自動(dòng)下載依賴項(xiàng)。這會(huì)花一點(diǎn)時(shí)間。你可以去和妹子聊一會(huì)兒了。。
如果你覺(jué)得這樣很麻煩的話,可以建立一個(gè)Gradle項(xiàng)目。之后根據(jù)上面的例子建立一個(gè)目錄:
└── src └── main └── java └── hello
但是無(wú)論是用上面的哪種方式,最后都需要在Gradle文件中添加依賴項(xiàng)。這個(gè)Gradle文件是build.gradle
。添加完依賴項(xiàng)
之后是這樣的:
buildscript { repositories { mavenCentral() } dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:1.3.3.RELEASE") } } apply plugin: 'java' apply plugin: 'eclipse' apply plugin: 'idea' apply plugin: 'spring-boot' jar { baseName = 'gs-spring-boot' version = '0.1.0' } repositories { mavenCentral() } sourceCompatibility = 1.8 targetCompatibility = 1.8 dependencies { // tag::jetty[] compile("org.springframework.boot:spring-boot-starter-web") { exclude module: "spring-boot-starter-tomcat" } compile("org.springframework.boot:spring-boot-starter-jetty") // end::jetty[] // tag::actuator[] compile("org.springframework.boot:spring-boot-starter-actuator") // end::actuator[] compile('org.springframework.boot:spring-boot-starter-data-jpa:1.3.3.RELEASE') compile('mysql:mysql-connector-java:5.1.13') testCompile("junit:junit") } task wrapper(type: Wrapper) { gradleVersion = '2.3' }
配置文件
在目錄src/main/resources/application.properties
下編輯配置文件。默認(rèn)是沒(méi)有這個(gè)文件和相應(yīng)的目錄的,自行創(chuàng)建。
spring.datasource.url = jdbc:mysql://localhost:3306/test spring.datasource.username = root spring.datasource.password = root #spring.datasource.driverClassName = com.mysql.jdbc.Driver # Specify the DBMS spring.jpa.database = MYSQL # Keep the connection alive if idle for a long time (needed in production) spring.datasource.testWhileIdle = true spring.datasource.validationQuery = SELECT 1 # Show or not log for each sql query spring.jpa.show-sql = true # Hibernate ddl auto (create, create-drop, update) spring.jpa.hibernate.ddl-auto = update # Naming strategy spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy # Use spring.jpa.properties.* for Hibernate native properties (the prefix is # stripped before adding them to the entity manager) # The SQL dialect makes Hibernate generate better SQL for the chosen database spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
無(wú)需java的配置類,或者什么XML配置文件。
使用配置項(xiàng)hibernate.ddl-auto = true,
項(xiàng)目所需的數(shù)據(jù)庫(kù)和相關(guān)表、列會(huì)自動(dòng)根據(jù)定義的實(shí)體類創(chuàng)建。點(diǎn)擊這里,查看更多配置的說(shuō)明。
創(chuàng)建一個(gè)簡(jiǎn)單地實(shí)體類
這里定義一個(gè)簡(jiǎn)單地實(shí)體類,并聲明為JPA實(shí)體。這個(gè)類的文件存放在目錄src\main\java\hello\Entities\
下。
package hello.Entities import javax.validation.constraints.NotNull import java.io.Serializable; import javax.persistence.*; /** * Created by Bruce on 2016/3/9. */ @Entity @Table(name = "user") data class User(@Id @GeneratedValue(strategy = GenerationType.AUTO) var id: Long? = 0, @Column(nullable = false) var name: String? = null, @Column(nullable = false) var email: String? = null) : Serializable { protected constructor() : this(id = null, name = null, email = null) { } }
這里使用了Kotlin里的data class。data class最大的優(yōu)點(diǎn)就是省去了定義getter和setter,以及toString()
的時(shí)間。這些都已經(jīng)默認(rèn)實(shí)現(xiàn)。所以,在使用data class的對(duì)象的時(shí)候直接可以使用name
、email
當(dāng)然還有id
這樣的屬性直接訪問(wèn)。
無(wú)參數(shù)的構(gòu)造函數(shù)是給JPA用的,所以訪問(wèn)級(jí)別設(shè)定為protected
。主構(gòu)造函數(shù)是用來(lái)創(chuàng)建和數(shù)據(jù)庫(kù)操作相關(guān)的對(duì)象的。
整個(gè)的整個(gè)類被@Entity
修飾,說(shuō)明整個(gè)類是一個(gè)JPA的實(shí)體類。@Table
聲明用來(lái)表明整個(gè)類對(duì)應(yīng)的數(shù)據(jù)庫(kù)表是哪一個(gè)。
@Id
修飾的User
的屬性id
,會(huì)被JPA認(rèn)為的對(duì)象的ID。同時(shí)@GeneratedValue(strategy = GenerationType.AUTO)
的修飾說(shuō)明這個(gè)ID是自動(dòng)生成的。
另外的兩個(gè)屬性name
和email
被@Column(nullable = false)
修飾。說(shuō)明兩個(gè)列都是不可以為空的,同時(shí)說(shuō)明兩個(gè)列的名字和屬性的名字是相同的。如果不同可以這樣@Column(nullable = false, name="XXXXXX")。
創(chuàng)建簡(jiǎn)單地查詢,或者說(shuō)Dao類
這個(gè)就更加的簡(jiǎn)單了。JPA會(huì)自動(dòng)在運(yùn)行時(shí)創(chuàng)建數(shù)據(jù)庫(kù)需要的增刪改查的實(shí)現(xiàn)。這個(gè)實(shí)現(xiàn)可以是根據(jù)我們給出的Repository
來(lái)實(shí)現(xiàn)的。
根據(jù)User
類,我們來(lái)實(shí)現(xiàn)一個(gè)UserDao(Repository):
package hello.Entities import org.springframework.data.repository.CrudRepository import org.springframework.transaction.annotation.Transactional @Transactional interface UserDao : CrudRepository<User, Long> { fun findByEmail(email: String): User? }
泛型的類型參數(shù)分別是user和user的id的類型:User
, Long
。我們可以定義增刪改查之外的Query。比如在上面的代碼里我們定義了一個(gè)findByEmail()
方法。具體的自定義查詢時(shí)的命名規(guī)則可以查看這里。
用Controller測(cè)試一下
數(shù)據(jù)庫(kù),Rest服務(wù)和書庫(kù)的連接都已經(jīng)搞定。那么,我們就來(lái)測(cè)試一下。
我們?cè)谀夸?code>src\main\java\hello\Controllers創(chuàng)建一個(gè)UserController
類來(lái)測(cè)試和數(shù)據(jù)庫(kù)的數(shù)據(jù)存取。
package hello.Controllers import hello.Entities.User import hello.Entities.UserDao import org.springframework.beans.factory.annotation.Autowired import org.springframework.web.bind.annotation.RestController import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.ResponseBody /** * Created by Bruce on 2016/3/9. */ @RestController class UserController { @Autowired private var userDao: UserDao? = null @RequestMapping("/create") @ResponseBody public fun create(name: String, email: String): User? { try { var newUser = User(name = name, email = email) userDao?.save(newUser) return newUser } catch(e: Exception) { return null } } @RequestMapping("/delete") @ResponseBody public fun delete(id: Long): String { try { var user = User(id) userDao?.delete(user) return id.toString() + "deleted" } catch(e: Exception) { return "delete error " + e.message.toString() } } @RequestMapping("/get-by-email") @ResponseBody public fun getByEmail(email: String): User? { try { var user = userDao?.findByEmail(email) if (user != null) { return user } else { return null } } catch(e: Exception) { return null } } @RequestMapping("/update") @ResponseBody public fun updateUser(id: Long, name: String, email: String): User? { try { var user: User? = userDao?.findOne(id) ?: return null user?.name = name user?.email = email userDao?.save(user) return user } catch(e: Exception) { return null } } }
測(cè)試URL可以是這樣的:
- /create?name=Jack&email=hello@234.com,使用指定的用戶名和郵箱在數(shù)據(jù)庫(kù)里生成一個(gè)新的user,id是自動(dòng)生成的。
- /delete?id=3, 刪除id值為3的user。
- /get-by-email?email=hello@234.com,注意Controller用到的UserDao.findByEmail()只返回一個(gè)user,所以如果有多個(gè) 返回值的話會(huì)報(bào)錯(cuò)。
- /update?id=1&email=what@123.com&name=Bruce,更新id為1的user。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 關(guān)于Spring Boot和Kotlin的聯(lián)合開(kāi)發(fā)
- spring boot + jpa + kotlin入門實(shí)例詳解
- 使用Spring boot + jQuery上傳文件(kotlin)功能實(shí)例詳解
- Spring Boot 與 Kotlin 使用JdbcTemplate連接MySQL數(shù)據(jù)庫(kù)的方法
- Spring Boot 與 kotlin 使用Thymeleaf模板引擎渲染web視圖的方法
- Kotlin + Spring Boot 請(qǐng)求參數(shù)驗(yàn)證的代碼實(shí)例
- Spring Boot 與 Kotlin 使用Redis數(shù)據(jù)庫(kù)的配置方法
- Spring Boot 與 Kotlin 上傳文件的示例代碼
- Spring Boot與Kotlin定時(shí)任務(wù)的示例(Scheduling Tasks)
- 利用Kotlin + Spring Boot實(shí)現(xiàn)后端開(kāi)發(fā)
相關(guān)文章
基于jdk動(dòng)態(tài)代理和cglib動(dòng)態(tài)代理實(shí)現(xiàn)及區(qū)別說(shuō)明
這篇文章主要介紹了基于jdk動(dòng)態(tài)代理和cglib動(dòng)態(tài)代理實(shí)現(xiàn)及區(qū)別說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-05-05MyBatis-Plus實(shí)現(xiàn)公共字段自動(dòng)填充功能詳解
在開(kāi)發(fā)中經(jīng)常遇到多個(gè)實(shí)體類有共同的屬性字段,這些字段屬于公共字段,也就是很多表中都有這些字段,能不能對(duì)于這些公共字段在某個(gè)地方統(tǒng)一處理,來(lái)簡(jiǎn)化開(kāi)發(fā)呢?MyBatis-Plus就提供了這一功能,本文就來(lái)為大家詳細(xì)講講2022-08-08教你通過(guò)B+Tree平衡多叉樹理解InnoDB引擎的聚集和非聚集索引
大家都知道B+Tree是從二叉樹演化而來(lái),在這之前我們來(lái)先了解二叉樹、平衡二叉樹、平衡多叉樹,這篇文章主要介紹了通過(guò)B+Tree平衡多叉樹理解InnoDB引擎的聚集和非聚集索引,需要的朋友可以參考下2022-01-01對(duì)handlerexecutionchain類的深入理解
下面小編就為大家?guī)?lái)一篇對(duì)handlerexecutionchain類的深入理解。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-07-07Java將Exception信息轉(zhuǎn)為String字符串的方法
今天小編就為大家分享一篇Java將Exception信息轉(zhuǎn)為String字符串的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-10-10詳解Java使用雙異步后如何保證數(shù)據(jù)一致性
這篇文章主要為大家詳細(xì)介紹了Java使用雙異步后如何保證數(shù)據(jù)一致性,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,有需要的小伙伴可以了解下2024-01-01Java利用jenkins做項(xiàng)目的自動(dòng)化部署
這篇文章主要介紹了Java利用jenkins做項(xiàng)目的自動(dòng)化部署,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-06-06