如何使用 Exposed 建立 OneToOne 关系

How to do a OneToOne relation using Exposed

我正在尝试使用 Exposed 在两个 table 之间建立一对一关系,我创建了一个用户 table 和一个 UserSettings Table,我想让用户 table 引用用户设置 table。我的问题是如何创建引用并创建具有引用设置的用户?

用户Table

object UserTable : IntIdTable("user") {
    val username = varchar("username", 16)
    val email = varchar("email", 254)
    val password = varchar("password_hash", 60)
    val settings = reference("id", UserSettingsTable)
}

用户实体

class User(id: EntityID<Int>): IntEntity(id), Principal {

    companion object : IntEntityClass<User>(UserTable)

    var username by UserTable.username
    var email by UserTable.email
    var password by UserTable.password
    val settings by UserSettings referrersOn UserTable.settings
}

设置Table

object UserSettingsTable : IntIdTable("user_settings") {
    var themeName = varchar("theme_name", 16).clientDefault {"dark"}
}

设置实体

open class UserSettings(id: EntityID<Int>) : IntEntity(id) {

    companion object : IntEntityClass<UserSettings>(UserSettingsTable)

    var themeName by UserSettingsTable.themeName
}

这就是我试图创建条目的方法

User.new {
    email = "email@gmail.com"
    username = "Someone"
    password = "test"
}.also { newUser ->
    UserSettings.new(newUser.id.value) {
        themeName = "dark"
    }
}

这是一个我还没有测试过的示例:

object UserSettingsTable : IntIdTable("user_settings") {
    var themeName = varchar("theme_name", 16).clientDefault {"dark"}
}

object UserTable : IntIdTable("user") {
    val username = varchar("username", 16)
    val email = varchar("email", 254)
    val password = varchar("password_hash", 60)
    val settings = reference("settings", UserSettingsTable)
}

class UserSettings(id: EntityID<Int>) : IntEntity(id) {

    companion object : IntEntityClass<UserSettings>(UserSettingsTable)

    var themeName by UserSettingsTable.themeName
}

class User(id: EntityID<Int>): IntEntity(id) {

    companion object : IntEntityClass<User>(UserTable)

    var username by UserTable.username
    var email by UserTable.email
    var password by UserTable.password
    var settings by UserSettings referencedOn UserTable.settings
}

fun createUser(): User {
    return User.new(1) {
        email = "email@gmail.com"
        username = "Someone"
        password = "test"
        settings = UserSettings.new(1) { themeName = "dark" }
    }
}

请注意,referencedOn 用于简单引用,而 referrersOn 用于集合。另外,Exposed

里面还有a limitation

Creating the entity and the reference in the same transaction does only work if you set the id column manually. If you're using UUIDTables and UUIDEntity you can do it like this:

transaction {
 //only works with UUIDTable and UUIDEntity
 StarWarsFilm.new (UUID.randomUUID()){
    ...
    actors = SizedCollection(listOf(actor))
  }
}