简体   繁体   English

级联删除 android 房间数据库 KOTLIN

[英]cascade delete in android room database KOTLIN

There are a bunch of questions like this in StackOverflow but most of that arent about room database, so I had to ask a new question. StackOverflow 中有很多这样的问题,但大部分都不是关于房间数据库的,所以我不得不问一个新问题。

I have an app that uses room database and that has near 4 tables and a big relationship between those tables, so for instance when I delete a user in user list fragment, that user delete(only userName and some personal info) but the user's TRANSACTIONS and LOANS hadn't been deleted.我有一个使用房间数据库的应用程序,它有近 4 个表并且这些表之间的关系很大,所以例如当我在用户列表片段中删除一个用户时,该用户删除(只有用户名和一些个人信息)但用户的 TRANSACTIONS并且LOANS没有被删除。 Someone told me I have to use Cascade delete but I didn't find much info about it.有人告诉我我必须使用Cascade delete ,但我没有找到太多关于它的信息。

My User class model:我的用户 class model:

@Entity(tableName = "user_info")
data class UserInfo(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "user_id")
var userId: Long =0L,
@ColumnInfo(name = "full_name")
var fullName:String?,
@ColumnInfo(name= "account_id")
var accountId: String?,
@ColumnInfo(name = "mobile_number")
var mobileNumber:String?,
@ColumnInfo(name = "phone_number")
var phoneNumber:String?,
@ColumnInfo(name = "date_of_creation")
var dateOfCreation:String?,
@ColumnInfo(name = "address")
var address:String?,
)

Transactions model class:事务 model class:

@Entity(tableName = "transactions")
data class Transactions(
    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "trans_id")
    var transId: Long = 0L,
    @ColumnInfo(name = "user_id")
    var userId: Long?,
    @ColumnInfo(name = "create_date")
    var createDate: String?,
    @ColumnInfo(name = "bank_id")
    var bankId: Long?,
    @ColumnInfo(name = "description")
    var description: String?,
    @ColumnInfo(name = "increase")
    var increase: String?,
    @ColumnInfo(name = "decrease")
    var decrease: String?,
    @ColumnInfo(name = "loan_number")
    var loanNumber: String?,
    @ColumnInfo(name = "total")
    var total: Long?,
    @ColumnInfo(name = "type")
    var type: String?
)

User DAO:用户 DAO:

 @Insert
suspend fun insert(ui: UserInfo): Long

@Update
suspend fun update(ui: UserInfo)

@Insert
suspend fun insertList(ui: MutableList<UserInfo>)

@Delete
suspend fun deleteUser(ui: UserInfo)

@Query("DELETE FROM user_info")
fun deleteAllUser()

@Query("SELECT user_info.user_id, user_info.full_name, transactions.total From user_info JOIN transactions ")
fun joinTable(): LiveData<List<UserAndMoney>>?

@Query("SELECT * from user_info WHERE user_id = :key")
fun get(key: Long): LiveData<UserInfo>?

@Query("SELECT * FROM user_info ORDER BY full_name DESC")
fun getAllUserInfo(): LiveData<List<UserInfo>>

@Query("SELECT * FROM user_info where full_name like '%' || :fullName || '%' ORDER BY full_name ASC")
fun searchUserName(fullName: String): LiveData<List<UserInfo>>

If It was not clear for you till now, let me makes it easy for you:如果到目前为止您还不清楚,让我为您简单介绍一下:

I need cascade delete that delets every thing about user and a record.我需要级联删除来删除有关用户和记录的所有内容。

CASCADE is an option of a Foreign Key constraint. CASCADE 是外键约束的一个选项。 So you would need to define Foreign Key constraints.所以你需要定义外键约束。 You define Foreign Key constraints in Room via the @Entity annotation.您可以通过 @Entity 注释在 Room 中定义外键约束。

As an example, as it would appear that a Transactions is related to a UserInfo via var userId: Long?, (column name user_id) you could have:-例如,看起来事务通过var userId: Long?, (column name user_id) 与 UserInfo 相关,您可以:-

@Entity(tableName = "transactions",
    foreignKeys = [
        ForeignKey(
            entity = UserInfo::class,
            parentColumns = ["user_id"],
            childColumns = ["user_id"],
            onDelete = ForeignKey.CASCADE, //<<<<<
            onUpdate = ForeignKey.CASCADE // Optional
        )
    ]
)
data class Transactions(
    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "trans_id")
    var transId: Long = 0L,
    @ColumnInfo(name = "user_id", index = true) // <<<<< best to have an index on the column, not required
    var userId: Long?,
    @ColumnInfo(name = "create_date")
    var createDate: String?,
    @ColumnInfo(name = "bank_id")
    var bankId: Long?,
    @ColumnInfo(name = "description")
    var description: String?,
    @ColumnInfo(name = "increase")
    var increase: String?,
    @ColumnInfo(name = "decrease")
    var decrease: String?,
    @ColumnInfo(name = "loan_number")
    var loanNumber: String?,
    @ColumnInfo(name = "total")
    var total: Long?,
    @ColumnInfo(name = "type")
    var type: String?
)

Note笔记

The constraint enforces referential integrity, that is a transaction can not be inserted/updated if the user_id value is not a value that exists in the user_id column of the user_info table.约束强制引用完整性,即如果 user_id 值不是 user_info 表的 user_id 列中存在的值,则无法插入/更新事务。

The CASCADE onUpdate will cascade a change to the user_id value in the user_info table to the respective transactions. CASCADE onUpdate 将对 user_info 表中的 user_id 值的更改级联到相应的事务。

Someone told me I have to use Cascade delete but I didn't find much info about it.有人告诉我我必须使用 Cascade delete,但我没有找到太多关于它的信息。

You could replicate the functionality without CASCADE.您可以在没有 CASCADE 的情况下复制该功能。

In short you could use简而言之,您可以使用

@Query("DELETE FROM transaction WHERE user_id=:userId")
fun cascadeDeletionsFromUser(userId: Long)
  • noting that if the Foreign Key constraint exists in the transactions table but didn't have an onDelete action specified, then the cascadeDeletionsFromUser function would have to be run before the user_info row is deleted.请注意,如果事务表中存在外键约束但未指定cascadeDeletionsFromUser操作,则必须在删除 user_info 行之前运行 cascadeDeletionsFromUser function。 Otherwise the user_info row could not be deleted as the FK constraint would inhibit the deletion.否则无法删除 user_info 行,因为 FK 约束会禁止删除。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM