延續前例
查詢指定學期成績,並且按平均進行排序,如下圖
create TABLE Student(
id bigint auto_increment PRIMARY KEY,
name VARCHAR(200) NOT NULL,
birthday DATE,
created TIMESTAMP,
gender VARCHAR(20) NOT NULL,
height DOUBLE NOT NULL,
weight DOUBLE NOT NULL,
student_id VARCHAR(20),
photo VARCHAR(100)
);
create TABLE Grade(
id bigint auto_increment PRIMARY KEY,
mandarin DOUBLE NOT NULL,
description VARCHAR(50) NOT NULL,
english DOUBLE NOT NULL,
math DOUBLE NOT NULL,
pe DOUBLE NOT NULL,
student_id bigint not null REFERENCES Student(id)
)
前述範例中 VoK 能夠將資料表映射到實體類,因為在Bootstrap.kt
已經設定好資料庫連線,在此使用Hikari-CP
管理JDB資料庫連接池 (connection pool)。
val cfg = HikariConfig().apply {
driverClassName = Driver::class.java.name
jdbcUrl = "jdbc:h2:mem:test;DB_CLOSE_DELAY=-1"
username = "sa"
password = ""
}
VaadinOnKotlin.dataSource = HikariDataSource(cfg)
設定好 jdbc url 並 setDataSource
初始化 connection pool後,只要使用db{}
即可取得資料庫連線,如下所示:
db {
handle.createQuery("select distinct description from Grade")
.mapTo(String::class.java)
.list()
}
vok-orm 提供了可直接執行SQL的彈性作法,一般而言,單一表單CRUD較傾向使用KEntity
所提供的save()
、create()
、delete()
、validate()
等方法,當上述方法皆無法達成目的時,即會採用此法。
範例 :
db {
handle.createQuery("create TABLE CATEGORY (id bigint auto_increment PRIMARY KEY, name varchar(200) NOT NULL );").executeUpdate()
}
db {
(0..100).forEach { Category(name = "cat $it").save() }
}
db {
handle.createUpdate("delete from Category where id = :id")
.bind("id", id)
.execute()
}
成績資料表 Grade
為實體映射類(Entity
),可直接使用db{}
從connection pool取得 connection。
在Grade
加入一靜態方法getSemester()
,請開啟Grade.kt
data class Grade(
override var id: Long? = null,
var student_id: Long? = null,
var description: String? = null,
var english: Double? = null,
var math: Double? = null,
var mandarin:Double? = null,
var pe: Double? = null
): KEntity<Long> {
companion object: Dao<Grade, Long>(Grade::class.java){
fun getSemester(): List<String> = db {
handle.createQuery("select distinct description from Grade")
.mapTo(String::class.java)
.list()
}
}
val student: Student?
get() = student_id?.let { Student.getById(student_id!!)} ?: null
}
因僅查詢description
欄位,使用mapTo()
方法將結果映射為字串型態List
comboBox<String>("學期"){
setItems(Grade.getSemester())
addValueChangeListener {
semester = value
}
}