JetBrains Exposed框架中的DAO CRUD操作详解
Exposed Kotlin SQL Framework 项目地址: https://gitcode.com/gh_mirrors/ex/Exposed
前言
JetBrains Exposed是一个轻量级的Kotlin SQL框架,提供了两种API风格:类型安全的DSL和轻量级的DAO(数据访问对象)。本文将重点介绍如何使用Exposed的DAO API进行基本的CRUD(创建、读取、更新、删除)操作。
什么是DAO模式
DAO(Data Access Object)是一种设计模式,它将底层数据访问操作与业务逻辑分离。在Exposed中,DAO通过实体类(Entity Class)来表示数据库表,每个实体实例对应表中的一行记录。
准备工作
在开始CRUD操作前,我们需要定义实体类和对应的表结构。假设我们有一个电影数据库,包含StarWarsFilmEntity
实体和对应的StarWarsFilmsTable
表。
创建操作(Create)
基本创建
使用.new()
函数创建新记录:
val movie = StarWarsFilmEntity.new {
name = "The Last Jedi"
sequelId = MOVIE_SEQUEL_ID
director = "Rian Johnson"
}
指定ID创建
如果需要手动指定ID值:
val movie2 = StarWarsFilmEntity.new(id = 2) {
name = "The Rise of Skywalker"
sequelId = MOVIE2_SEQUEL_ID
director = "J.J. Abrams"
}
复合ID创建
对于复合主键的表,使用CompositeID
:
val directorId = CompositeID {
it[DirectorsTable.name] = "J.J. Abrams"
it[DirectorsTable.guildId] = UUID.randomUUID()
}
val director = DirectorEntity.new(directorId) {
genre = Genre.SCI_FI
}
读取操作(Read)
基本属性访问
读取属性就像访问普通Kotlin类属性:
val movieName = movie.name
注意:实体ID是EntityID
类型,获取实际值需要使用.value
:
val movieId: Int = movie.id.value
查询方法
- 获取所有记录:
val allMovies = StarWarsFilmEntity.all()
- 条件查询:
val specificMovie = StarWarsFilmEntity.find {
StarWarsFilmsTable.sequelId eq MOVIE_SEQUELID
}
- 按ID查询:
val movie = StarWarsFilmEntity.findById(2)
复合ID查询
val directorId = CompositeID {
it[DirectorsTable.name] = "J.J. Abrams"
it[DirectorsTable.guildId] = UUID.randomUUID()
}
val director = DirectorEntity.findById(directorId)
连接查询
查找给第二部星球大战电影评分超过5的用户:
val query = UsersTable.innerJoin(UserRatingsTable)
.innerJoin(StarWarsFilmsTable)
.select(UsersTable.columns)
.where {
StarWarsFilmsTable.sequelId eq MOVIE_SEQUELID and
(UserRatingsTable.value greater MIN_MOVIE_RATING)
}.withDistinct()
val users = UserEntity.wrapRows(query).toList()
结果排序
- 升序排序:
val moviesByAscOrder = StarWarsFilmEntity.all().sortedBy { it.sequelId }
- 降序排序:
val moviesByDescOrder = StarWarsFilmEntity.all().sortedByDescending { it.sequelId }
更新操作(Update)
基本更新
直接修改属性值:
movie.name = "Episode VIII – The Last Jedi"
注意:Exposed不会立即更新数据库,而是在事务结束时或下次查询前执行更新。
按ID更新
val updatedMovie = StarWarsFilmEntity.findByIdAndUpdate(2) {
it.name = "Episode VIII – The Last Jedi"
}
按条件更新
val updatedMovie2 = StarWarsFilmEntity.findSingleByAndUpdate(
StarWarsFilmsTable.name eq "The Last Jedi"
) {
it.name = "Episode VIII – The Last Jedi"
}
删除操作(Delete)
删除记录非常简单:
movie.delete()
高级技巧
查询作为表达式
例如,按城市用户数排序城市:
val citiesSortedByUserCount = CityEntity.all()
.sortedByDescending { city ->
UserEntity.find { UsersTable.cityId eq city.id }.count()
}
自动填充字段
可以在实体类中添加计算字段或自动填充字段,这些字段不会持久化到数据库,但可以在业务逻辑中使用。
总结
Exposed的DAO API提供了一种面向对象的方式来操作数据库,使得Kotlin开发者可以用熟悉的语法进行数据库操作。通过本文介绍的各种CRUD操作,你应该能够处理大多数数据库交互场景。记住,所有数据库操作都应该在事务中执行,这是Exposed的基本要求。
对于更复杂的查询,可以结合使用DSL API和DAO API,发挥Exposed的最大威力。
Exposed Kotlin SQL Framework 项目地址: https://gitcode.com/gh_mirrors/ex/Exposed
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考