如何在Kotlin Exposed中实现DATE_ADD?使用日期函数加天数并比较
要实现类似DATE_ADD(start_date, INTERVAL 1 DAY)的功能,同时给Column<DateTime>字段添加指定天数后和目标日期比较,Exposed提供了几种灵活的方式,下面结合你的表结构给出具体实现:
方案一:直接使用数据库原生DATE_ADD函数(MySQL等适配数据库)
Exposed针对支持DATE_ADD的数据库(比如MySQL)提供了对应的扩展函数,写法最贴近你熟悉的SQL语法:
首先导入必要的扩展:
import org.jetbrains.exposed.sql.dateAdd import org.jetbrains.exposed.sql.interval import org.joda.time.DateTime
然后基于你的表结构,写出查询语句:
// 替换成你的目标日期和要添加的天数 val targetDate = DateTime.now().plusMonths(1) val daysToAdd = 3 val expiredAuthorizations = UserAuthorizationDataTable.select { // 给generated_on字段添加X天,然后和目标日期比较 UserAuthorizationDataTable.generatedOn.dateAdd(interval(daysToAdd, "DAY")) lessEq targetDate }
这段代码生成的SQL就是你想要的:
SELECT id, generated_on FROM user_auth_table WHERE DATE_ADD(generated_on, INTERVAL 3 DAY) <= ?
方案二:跨数据库兼容的日期加法(推荐)
如果你的项目需要兼容多种数据库(比如同时支持MySQL、PostgreSQL、SQLite),可以用Exposed的Duration加法方式,底层会自动适配不同数据库的语法:
import org.joda.time.DateTime import org.joda.time.Duration val targetDate = DateTime.now() val daysToAdd = 7 val query = UserAuthorizationDataTable.select { (UserAuthorizationDataTable.generatedOn + Duration.standardDays(daysToAdd)) lessEq targetDate }
比如在PostgreSQL中,这段代码会生成:
SELECT id, generated_on FROM user_auth_table WHERE generated_on + INTERVAL '7 days' <= ?
而在SQLite中,会自动转成基于秒数的加法:
SELECT id, generated_on FROM user_auth_table WHERE generated_on + ? * 86400 <= ?
针对Java 8+ LocalDateTime的适配
如果你的项目用的是Java 8的LocalDateTime而不是Joda Time,只需要替换对应的类型和Duration类即可:
import java.time.LocalDateTime import java.time.Duration // 假设表字段定义为: // val generatedOn: Column<LocalDateTime> = datetime("generated_on").default(LocalDateTime.now()) val targetDate = LocalDateTime.now() val daysToAdd = 5 val query = UserAuthorizationDataTable.select { (UserAuthorizationDataTable.generatedOn + Duration.ofDays(daysToAdd)) lessEq targetDate }
完整示例代码
结合你提供的表结构,这里给出一个可直接运行的查询示例:
open class DBTable(tableName: String) : Table(tableName) { val id = integer("id").autoIncrement().primaryKey() } object UserAuthorizationDataTable : DBTable("user_auth_table") { val generatedOn: Column<DateTime> = datetime("generated_on").default(DateTime.now()) // 其他字段可以在这里添加,比如user_id、token等 } fun main() { // 初始化数据库连接(这里省略,根据你的项目配置来) // Database.connect("jdbc:mysql://localhost:3306/your_db", driver = "com.mysql.cj.jdbc.Driver", user = "root", password = "password") val targetDate = DateTime.now() val daysToAdd = 3 val expiredRecords = UserAuthorizationDataTable.select { UserAuthorizationDataTable.generatedOn.dateAdd(interval(daysToAdd, "DAY")) lessEq targetDate } expiredRecords.forEach { row -> println("ID: ${row[UserAuthorizationDataTable.id]}, Generated On: ${row[UserAuthorizationDataTable.generatedOn]}") } }
内容的提问来源于stack exchange,提问作者Tech Drago

