首先我們改寫一下資料表的格式
object Users : IntIdTable() {
val name = varchar("name", length = 50)
val age = integer("age")
}
使用 IntIdTable
比起之前的 Table
更加簡潔
針對單一資料物件的操作,我們要加上一個新的類別 UserEntity
class UserEntity(id: EntityID<Int>) : IntEntity(id) {
companion object : IntEntityClass<UserEntity>(Users)
var name by Users.name
var age by Users.age
}
至於資料表裡面的操作,我們改寫成這樣
suspend fun create(user: ExposedUser): Int = dbQuery {
val entity = UserEntity.new {
name = user.name
age = user.age
}
entity.id.value
}
suspend fun read(id: Int): ExposedUser? = dbQuery {
UserEntity.findById(id)?.let { ExposedUser(it.name, it.age) }
}
suspend fun update(id: Int, user: ExposedUser) {
dbQuery {
UserEntity.findById(id)?.apply {
name = user.name
age = user.age
}
}
}
suspend fun delete(id: Int) {
dbQuery {
UserEntity.findById(id)?.delete()
}
}
接著我們就可以照樣使用 UserService
了!使用的方式和之前沒有差異
我們可以撰寫一個自動化測試來確認 UserService
的行爲。我們加上一個新檔案 src/test/kotlin/UserServiceTest.kt
package com.example
import kotlinx.coroutines.runBlocking
import org.jetbrains.exposed.sql.Database
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertNotNull
import kotlin.test.assertNull
class UserServiceTest {
private fun newDb(): Database = Database.connect(
url = "jdbc:h2:mem:user_service_test_${System.nanoTime()};DB_CLOSE_DELAY=-1",
user = "root",
driver = "org.h2.Driver",
password = "",
)
@Test
fun testCreateAndRead() = runBlocking {
val service = UserService(newDb())
val newUser = ExposedUser(name = "Alice", age = 30)
val id = service.create(newUser)
assertNotNull(id)
val read = service.read(id)
assertNotNull(read)
assertEquals("Alice", read.name)
assertEquals(30, read.age)
}
@Test
fun testUpdate() = runBlocking {
val service = UserService(newDb())
val id = service.create(ExposedUser("Bob", 22))
service.update(id, ExposedUser("Bobby", 23))
val read = service.read(id)
assertNotNull(read)
assertEquals("Bobby", read.name)
assertEquals(23, read.age)
}
@Test
fun testDelete() = runBlocking {
val service = UserService(newDb())
val id = service.create(ExposedUser("Charlie", 40))
// ensure it exists first
assertNotNull(service.read(id))
service.delete(id)
val after = service.read(id)
assertNull(after)
}
@Test
fun testReadNonExistent() = runBlocking {
val service = UserService(newDb())
val result = service.read(999999)
assertNull(result)
}
}
運作測試通過之後,我們就可以更加確保我們的 UserService
沒有問題了!
今天的部分就到這邊,我們明天見!