Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何避免kotlin上的N+1查询问题已公开。(当通过DAO的Reference.id.value字段获取值时)_Kotlin_Kotlin Exposed - Fatal编程技术网

如何避免kotlin上的N+1查询问题已公开。(当通过DAO的Reference.id.value字段获取值时)

如何避免kotlin上的N+1查询问题已公开。(当通过DAO的Reference.id.value字段获取值时),kotlin,kotlin-exposed,Kotlin,Kotlin Exposed,我在Kotlin JVM项目上用作O/R映射器。 版本:0.17.6 当我从Exposed的引用方法定义的DAOAPI列中获取外键列的值时,我遇到了N+1查询问题 我用一个变通代码解决了这个问题,但是有人知道正确的解决方案吗 情况是这样的 有两个表users,user_addresses和一个tableuser_addresses表在otheruser表上有一个外键引用 object Users : LongIdTable("users") { val name = varchar("n

我在Kotlin JVM项目上用作O/R映射器。 版本:0.17.6

当我从Exposed的引用方法定义的DAOAPI列中获取外键列的值时,我遇到了N+1查询问题

我用一个变通代码解决了这个问题,但是有人知道正确的解决方案吗

情况是这样的

有两个表users,user_addresses和一个tableuser_addresses表在otheruser表上有一个外键引用

object Users : LongIdTable("users") {
    val name = varchar("name", 30)
}
class User(id: EntityID<Long>) : LongEntity(id) {
    companion object : LongEntityClass<User>(Users)

    var name by Users.name
}

object UserAddresses : LongIdTable("user_addresses") {
    val user = reference("user_id", Users)
    val address = varchar("address", 30)
}
class UserAddress(id: EntityID<Long>) : LongEntity(id) {
    companion object : LongEntityClass<UserAddress>(UserAddresses)

    var user by User.referencedOn(UserAddresses.user)
    var address by UserAddresses.address

    fun toRow(): UserAddressRow {    
        return UserAddressRow(
            id.value,
            user.id.value,
            address
        )
    }
}

data class UserAddressRow(val id: Long, val userId: Long, val address: String)
测试数据

INSERT INTO users (id, name) VALUES (1, 'A');
INSERT INTO users (id, name) VALUES (2, 'B');
INSERT INTO user_addresses (user_id, address) VALUES (1, 'X');
INSERT INTO user_addresses (user_id, address) VALUES (1, 'Y');
INSERT INTO user_addresses (user_id, address) VALUES (2, 'Z');
SQL查询日志公开调试日志

[] 2019-11-22 10:41:55.656 [main] DEBUG [cid- uid--] Exposed - SELECT user_addresses.id, user_addresses.user_id, user_addresses.address FROM user_addresses
[] 2019-11-22 10:41:55.668 [main] DEBUG [cid- uid--] Exposed - SELECT users.id, users."name" FROM users WHERE users.id = 1
[] 2019-11-22 10:41:55.670 [main] DEBUG [cid- uid--] Exposed - SELECT users.id, users."name" FROM users WHERE users.id = 2
如果我使用readValue而不是user.id,问题就解决了。 我不确定这个变通方法是否正确。请帮帮我

   fun toRow(): UserAddressRow {    
        return UserAddressRow(
            id.value,
            readValues[UserAddressTable.user].value,
            address
        )
    }

我注意到下面的简单模式会更好

//Define userId column in DAO (UserAddress class), and use it
class UserAddress(id: EntityID<Long>) : LongEntity(id) {
    companion object : LongEntityClass<UserAddress>(UserAddresses)

    var user by User.referencedOn(UserAddresses.user)
    var userId by UserAddresses.user
    var address by UserAddresses.address

    fun toRow(): UserAddressRow {
        return UserAddressRow(
            id.value,
            userId.value,
            address
        )
    }
}

//There is only one SQL statement executed
//SELECT user_addresses.id, user_addresses.user_id, user_addresses.address FROM user_addresses

请查看此处的文档,谢谢您的建议!!这是一次伟大的学习。但实际上,在这种情况下,一些无用的SQL是在使用渴望加载时执行的。这里是细节。急切加载代码:UserAddress.all.withUserAddress::user。已执行无用SQL:从1、1、2中的users.id所在的users中选择users.id、users.name。不需要从users表中选择,所以我只想执行用于查询user\u addresses表。
//Define userId column in DAO (UserAddress class), and use it
class UserAddress(id: EntityID<Long>) : LongEntity(id) {
    companion object : LongEntityClass<UserAddress>(UserAddresses)

    var user by User.referencedOn(UserAddresses.user)
    var userId by UserAddresses.user
    var address by UserAddresses.address

    fun toRow(): UserAddressRow {
        return UserAddressRow(
            id.value,
            userId.value,
            address
        )
    }
}

//There is only one SQL statement executed
//SELECT user_addresses.id, user_addresses.user_id, user_addresses.address FROM user_addresses