Room 数据库中的@ForeignKey 和@Relation 注释有什么区别?

编程入门 行业动态 更新时间:2024-10-27 22:21:08
本文介绍了Room 数据库中的@ForeignKey 和@Relation 注释有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

限时送ChatGPT账号..

我无法理解这些注释之间的区别.在我的用例中,我想在表之间创建一对多关系.并找到了两个选项:一个是@ForeignKey,另一个是@Relation

I can't understand difference between those annotations. In my use case i want create one-to-many relation between tables. And found two options: one with @ForeignKey and another with @Relation

我还发现,如果我更新该行(例如使用 OnCoflictStrategy.Replace),我将丢失该行的外键,这是真的吗?

Also i found that if i update the row (e.g. with OnCoflictStrategy.Replace) i will lost foreign key for this row is it true?

推荐答案

A @ForeignKey 定义了一个约束(又名规则),要求子列存在于父列中).如果试图打破该规则,则会发生冲突(可以通过 onDelete/onUpdate 定义以多种方式处理).

A @ForeignKey defines a constraint (aka rule) that requires that the child column(s) exist in the parent column(s). If an attempt is made to break that rule then a conflict occurs (which may be handled various ways by the onDelete/onUpdate definition).

@Relationship 用于定义一种关系,其中在父对象中返回多个子对象(可能是外键子对象).

An @Relationship is used to define a relationship where a number of child (perhaps Foreign Key children) objects are returned in the parent object.

在这一切之下 @Relation 自动(有效地)连接表并生成子对象的数量.虽然 @ForeignKey 只影响架构(onDelete/onUpdate 处理除外),但它不会导致连接相应的表.

Underneath it all @Relation automatically (effectively) joins the tables and generates the number of child objects. Whilst a @ForeignKey just affects the schema (with the exception of onDelete/onUpdate handling), it does not result in the respective tables being joined.

也许考虑以下:-

服务实体

@Entity(
    tableName = "services"
)
class Services {

    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "services_id")
    var id: Long = 0
    var service_date: String = ""
    var user_mobile_no: String = ""

}

ServiceDetail 实体 :-

@Entity(
    tableName = "service_detail",
    foreignKeys = [
        ForeignKey(
            entity = Services::class,
            parentColumns = ["services_id"],
            childColumns = ["services_id"],onDelete = ForeignKey.SET_DEFAULT
        )
    ]
)
class ServiceDetail {

    @PrimaryKey
    var id: Long? = null;
    var services_id: Long = 0;
    @ColumnInfo(defaultValue = "1")
    var service_type_id: Long = 0;

    constructor()

    @Ignore
    constructor(services_id: Long, service_type_id: Long) {
        this.services_id = services_id
        this.service_type_id = service_type_id
    }
}

这是说,为了添加 ServiceDetail,services_id 列的值必须是 services 表的 services_id 列中存在的值,否则会发生冲突.此外,如果从 services 表中删除了一行,那么 service_detail 表中引用该行的任何行也将被删除(否则无法从 services 表中删除该行).

This is saying that in order to add a ServiceDetail then the value of the services_id column MUST be a value that exists in the services_id column of the services Table, otherwise a conflict will happen. And additionally if a row is deleted from the services table then any rows in the service_detail table that reference that row will also be deleted (otherwise the row couldn;t be deleted from the services table).

现在考虑这个普通类(POJO),它不是实体(又名表):-

Now consider this normal class (POJO), which is NOT an entity (aka table) :-

class ServiceWithDetail {

    @Embedded
    var services: Services? = null

    @Relation(entity = ServiceDetail::class,parentColumn = "services_id",entityColumn = "services_id")
    var serviceDetail: List<ServiceDetail>? = null
}

这大致是说,当你请求一个 ServiceWithDetail 对象然后得到一个 services 对象以及相关的 service_detail 对象的列表

This is roughly saying when you ask for a ServiceWithDetail object then get a services object along with a list of the related service_detail objects

你会有一个 Dao,例如 :-

You would have a Dao such as :-

@Query("SELECT * FROM services")
fun getAllServices() :List<ServiceWithDetail>

因此它将从 services 表中获取所有服务以及相关的服务(即 services_detail 中的 services_id 与正在处理的当前服务行的 services_id 相同).

So it will get all the services from the services table along with the related (i.e. where the services_id in the services_detail is the same as the services_id of the current services row being processed).

onConflictStrategy

REPLACE 执行以下操作:-

当违反 UNIQUE 或 PRIMARY KEY 约束时,REPLACE算法删除导致约束的预先存在的行在插入或更新当前行和命令继续正常执行.

When a UNIQUE or PRIMARY KEY constraint violation occurs, the REPLACE algorithm deletes pre-existing rows that are causing the constraint violation prior to inserting or updating the current row and the command continues executing normally.

如果一个 NOT NULL 约束发生冲突,REPLACE 冲突解决方法替换 NULLvalue 与该列的默认值,或者如果该列没有默认值,则使用 ABORT 算法.如果一个 CHECK 约束或者发生外键约束冲突,REPLACE 冲突解析算法的工作原理类似于 ABORT.

If a NOT NULL constraint violation occurs, the REPLACE conflict resolution replaces the NULL value with the default value for that column, or if the column has no default value, then the ABORT algorithm is used. If a CHECK constraint or foreign key constraint violation occurs, the REPLACE conflict resolution algorithm works like ABORT.

当 REPLACE 冲突解决策略删除行以便满足约束,删除触发器当且仅当递归时触发触发器已启用.

When the REPLACE conflict resolution strategy deletes rows in order to satisfy a constraint, delete triggers fire if and only if recursive triggers are enabled.

不会为被删除的行调用更新钩子更换冲突解决策略.REPLACE 也不会增加更改计数器.本段中定义的异常行为可能会在未来版本中更改.REPLACE

The update hook is not invoked for rows that are deleted by the REPLACE conflict resolution strategy. Nor does REPLACE increment the change counter. The exceptional behaviors defined in this paragraph might change in a future release.REPLACE

因此,您所经历的行为的可能性.但是,这取决于更新正在执行的操作.如果 ForeignKey(s) 的值不同,那么它们应该,假设没有外键冲突,用新的有效值替换外键值.如果外键值不变,则替换行将具有相同的外键.

Hence, the potential for the behaviour that you have experienced. However, it depends upon what the update is doing. If the value for the ForeignKey(s) differ then they should, assuming there is no Foreign Key conflict replace the foreign key value with the new valid value. If the Foreign Key value(s) is(are) unchanged then replacement row will have the same Foreign Keys.

这篇关于Room 数据库中的@ForeignKey 和@Relation 注释有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

更多推荐

[db:关键词]

本文发布于:2023-04-23 03:50:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1034909.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:数据库中   注释   有什么区别   Room   Relation

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!