Kotlin学习随笔一 - 简单需求和项目初始化

Kotlin是对Java的一个简练的封装,提供了很多便利性的语法,熟练使用后,会大大缩减代码的行数,提高编码的速度。

具体Kotlin的优劣,网上很多评论,有兴趣的可以去看看,我们开始我们简单的demo开发。

需求:最简单的用户的CRUD,提供REST服务

开发工具:IDEA

Java框架:Springboot

数据库:Mysql

ORM:Hibernate JPA

好,下面来感受一下Kotlin的魅力,首先我们用IDEA新建一个基于Kotlin的Springboot项目,Kotlin是IntelliJ 公司推出的产品,所以IDEA原生就支持该语法。

目前的代码结构如下:可参见Github

 

首先我们先来看看实体的定义:

 1 package com.huangyu.hellokotlin.dao
 2 
 3 import kotlinx.serialization.Serializable
 4 import java.util.*
 5 import javax.persistence.GeneratedValue
 6 import javax.persistence.GenerationType
 7 import javax.persistence.Id
 8 import javax.persistence.MappedSuperclass
 9 
10 @Serializable
11 @MappedSuperclass
12 open class BaseEntity(@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
13                       var id: Long = 0,
14                       var available: Boolean = true,
15                       var logicDel: Boolean = false,
16                       var createdTime: Date = Date())
BaseDto
 1 package com.huangyu.hellokotlin.dao
 2 
 3 import com.fasterxml.jackson.annotation.JsonIgnoreProperties
 4 import javax.persistence.*
 5 
 6 @Entity @Table(name = "kotlin_users")
 7 data class User(
 8         var name: String = "",
 9         var age: String? = null,
10         var phone: String = "",
11         @OneToMany(mappedBy = "user", cascade = [CascadeType.ALL]) @JsonIgnoreProperties("carList", "user") var carList: List<Car>? = null
12 ) : BaseEntity()
13 
14 @Entity @Table(name = "kotlin_user_cars")
15 data class Car(
16         var name: String = "",
17         var brand: String = "",
18         @ManyToOne(cascade = [CascadeType.ALL]) @JoinColumn(name = "user_id") var user: User? = null
19 ) : BaseEntity()
UserDtos

Kotlin文件以.kt结尾,同时一个kt文件中允许多个class的定义,它会自动转换成相应的Java代码。

BaseDto中定义的 BaseEntity为基类,定义了Jpa需要的主键ID,以及一些业务需要的 available、logicDel等字段。各位可发现,其实Kotlin定义class并没有像Java那样定义一些字段,然后get set 方法。

而是在方法声明中,对变量进行定义,并且,此时可以赋初始值,节省了很多的代码量,当然,你也可以在class 的主体中进行定义。

UserDtos中定义的User和Car是一对多的关系,使用的Jpa Annotation进行标识,语法跟Java基本一致,大家注意实体定义最后的 : BaseEntity() 表示继承。

然后我们看一下其他代码,

Service:

 1 package com.huangyu.hellokotlin.service
 2 
 3 import com.huangyu.hellokotlin.dao.User
 4 import org.springframework.data.domain.Page
 5 
 6 interface UserService {
 7     fun add(user: User): User
 8     fun get(id: Long?): User
 9     fun page(pageIndex: Int, pageSize: Int): Page<User>
10     fun del(id: Long?)
11 }
UserService
 1 package com.huangyu.hellokotlin.service.impl
 2 
 3 import com.huangyu.hellokotlin.dao.Car
 4 import com.huangyu.hellokotlin.dao.User
 5 import com.huangyu.hellokotlin.dao.repo.CarRepository
 6 import com.huangyu.hellokotlin.dao.repo.UserRepository
 7 import com.huangyu.hellokotlin.service.UserService
 8 import org.springframework.beans.factory.annotation.Autowired
 9 import org.springframework.data.domain.Page
10 import org.springframework.data.domain.PageRequest
11 import org.springframework.stereotype.Service
12 
13 @Service
14 class UserServiceImpl : UserService {
15     @Autowired lateinit var userRepository: UserRepository
16     @Autowired lateinit var carRepository: CarRepository
17 
18     override fun add(user: User): User {
19         if (user.id != 0L) {
20             val existedUser: User = userRepository.findOne(user.id)
21             for (car in existedUser.carList!!)
22                 carRepository.delete(car)
23         }
24 
25         for (car: Car in user.carList!!)
26             car.user = user
27         return userRepository.save(user)
28     }
29 
30     override fun get(id: Long?): User {
31         return userRepository.getOne(id)
32     }
33 
34     override fun page(pageIndex: Int, pageSize: Int): Page<User> {
35         val pageRequest = PageRequest(pageIndex, pageSize)
36         return userRepository.findAll(pageRequest)
37     }
38 
39     override fun del(id: Long?) {
40         val user = userRepository.getOne(id)
41         for (car: Car in user.carList!!)
42             carRepository.delete(car)
43         userRepository.delete(id)
44     }
45 }
ServiceImpl

Repository:

1 package com.huangyu.hellokotlin.dao.repo
2 
3 import com.huangyu.hellokotlin.dao.Car
4 import com.huangyu.hellokotlin.dao.User
5 import org.springframework.data.jpa.repository.JpaRepository
6 
7 interface UserRepository : JpaRepository<User, Long>
8 interface CarRepository : JpaRepository<Car, Long>
UserRepos

Controller:

 1 package com.huangyu.hellokotlin.web
 2 
 3 import com.google.gson.GsonBuilder
 4 import com.huangyu.common.gson.GsonDateTypeAdapter
 5 import com.huangyu.common.gson.GsonLongTypeAdapter
 6 import com.huangyu.common.web.ApiResponse
 7 import com.huangyu.hellokotlin.dao.User
 8 import com.huangyu.hellokotlin.dao.page.BootstrapPage
 9 import com.huangyu.hellokotlin.service.UserService
10 import org.springframework.beans.factory.annotation.Autowired
11 import org.springframework.web.bind.annotation.RequestMapping
12 import org.springframework.web.bind.annotation.RestController
13 import java.util.*
14 
15 @RestController
16 @RequestMapping("user")
17 class UserController {
18 
19     @Autowired lateinit var userService: UserService
20 
21     @RequestMapping("add")
22     fun addUser(userJson: String): ApiResponse {
23         val gson = GsonBuilder().serializeNulls().registerTypeAdapter(Long::class.java, GsonLongTypeAdapter()).registerTypeAdapter(Date::class.java, GsonDateTypeAdapter()).create()
24         var user = gson.fromJson(userJson, User::class.java)
25         return ApiResponse.ok(userService.add(user))
26     }
27 
28     @RequestMapping("get")
29     fun getUser(id: Long?): ApiResponse {
30         return ApiResponse.ok(userService.get(id))
31     }
32 
33     @RequestMapping("page")
34     fun getUserPage(pageIndex: Int, pageSize: Int): ApiResponse {
35         val page = userService.page(pageIndex, pageSize)
36         val bootstrapPage = BootstrapPage(Integer.parseInt(page.totalElements.toString()), page.toList())
37         return ApiResponse.ok(bootstrapPage)
38     }
39 
40     @RequestMapping("del")
41     fun delUser(id: Long?): ApiResponse {
42         userService.del(id)
43         return ApiResponse.ok()
44     }
45 }
UserController

Test:

 1 package com.huangyu.hellokotlin.test
 2 
 3 import com.google.gson.Gson
 4 import com.google.gson.GsonBuilder
 5 import com.huangyu.Application
 6 import com.huangyu.common.gson.GsonDateTypeAdapter
 7 import com.huangyu.common.gson.GsonLongTypeAdapter
 8 import com.huangyu.common.web.ApiResponse
 9 import com.huangyu.common.web.ReturnCodeEnum
10 import com.huangyu.hellokotlin.dao.Car
11 import com.huangyu.hellokotlin.dao.User
12 import com.huangyu.hellokotlin.dao.repo.UserRepository
13 import org.junit.Before
14 import org.junit.Test
15 import org.junit.runner.RunWith
16 import org.springframework.beans.factory.annotation.Autowired
17 import org.springframework.boot.test.context.SpringBootTest
18 import org.springframework.boot.test.web.client.TestRestTemplate
19 import org.springframework.test.context.junit4.SpringRunner
20 import java.util.*
21 
22 var userId: Long = 0
23 
24 @RunWith(SpringRunner::class)
25 @SpringBootTest(classes = [Application::class], webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
26 class UserTest {
27 
28     @Autowired lateinit var testRestTemplate: TestRestTemplate
29     @Autowired lateinit var userRepository: UserRepository
30 
31     @Before
32     fun clear() {
33         userRepository.deleteAll()
34     }
35 
36     @Test fun userTest() {
37         add()
38         get()
39     }
40 
41     fun add() {
42         var user = createUser()
43 
44         val gson = GsonBuilder().serializeNulls().registerTypeAdapter(Long::class.java, GsonLongTypeAdapter()).registerTypeAdapter(Date::class.java, GsonDateTypeAdapter()).create()
45         val userJson = gson.toJson(user, User::class.java)
46         val result = Gson().fromJson<ApiResponse>(testRestTemplate.getForObject(TestURL.addUser + "?userJson={userJson}", String::class.java, userJson), ApiResponse::class.java)
47         assert(result.code == ReturnCodeEnum.success.ordinal)
48         user = gson.fromJson(result.data.toString(), User::class.java)
49 
50         userId = user.id
51     }
52 
53     private fun createUser(): User {
54         var user = User()
55         user.age = 35.toString()
56         user.name = "wangyu"
57         user.phone = "186-8949-5151"
58 
59         val carList = ArrayList<Car>()
60         val car = Car()
61         car.brand = "mazda"
62         car.name = "alexa"
63 
64         carList.add(car)
65         user.carList = carList
66         return user
67     }
68 
69     fun get() {
70         val result = Gson().fromJson<ApiResponse>(testRestTemplate.getForObject(TestURL.getUser + "?id=" + userId, String::class.java), ApiResponse::class.java)
71         assert(result.code == ReturnCodeEnum.success.ordinal)
72         val gson = GsonBuilder().serializeNulls().registerTypeAdapter(Long::class.java, GsonLongTypeAdapter()).registerTypeAdapter(Date::class.java, GsonDateTypeAdapter()).create()
73         val user: User = gson.fromJson<User>(result.data.toString(), User::class.java)
74         assert(user.id == userId)
75     }
76 }
77 
78 // 22000 + 30000 + 15000 + 10000
UserTest

Test代码是基于controller层进行web restful 接口测试。

以上是基本的代码,后续会持续更改。

 

转载于:https://www.cnblogs.com/szwangyu51/p/9880324.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值