【问题标题】:add unique constraint in room database to multiple column将房间数据库中的唯一约束添加到多列
【发布时间】:2018-08-04 08:25:48
【问题描述】:

我在房间里有一个实体

@Entity(foreignKeys ={
        @ForeignKey(entity = Label.class, parentColumns = "_id", childColumns = "labelId", onDelete = CASCADE),
        @ForeignKey(entity = Task.class, parentColumns = "_id", childColumns = "taskId", onDelete = CASCADE)
})
public class LabelOfTask extends Data{
    @ColumnInfo(name = "labelId")
    private Integer labelId;
    @ColumnInfo(name = "taskId")
    private Integer taskId;
}

该实体的sql语法如下

CREATE TABLE `LabelOfTask` (
    `_id` INTEGER PRIMARY KEY AUTOINCREMENT,
     `labelId` INTEGER,
     `taskId` INTEGER,
     FOREIGN KEY(`labelId`) REFERENCES `Label`(`_id`) ON UPDATE NO ACTION ON DELETE CASCADE ,
     FOREIGN KEY(`taskId`) REFERENCES `Task`(`_id`) ON UPDATE NO ACTION ON DELETE CASCADE
 );

但是如果我想将以下约束附加到表的自动生成的 sql 架构中,我需要在实体类中添加什么更改或注释

unique (labelId, taskId)

最终我想使用房间库使 labelId 和 taskId 的组合在表(或房间实体)中唯一。

【问题讨论】:

  • 不支持对列的普通 UNIQUE 约束,而不是通过索引。
  • 索引?你的意思是主键?

标签: android sqlite database-design android-room android-architecture-components


【解决方案1】:

不支持通过索引以外的列上的普通 UNIQUE 约束。

您可以通过将 @Index 注释的唯一属性设置为 true 来强制执行此唯一性属性。以下代码示例 (Java) 可防止表中有两行包含相同的 firstName 和 lastName 列值集:

@Entity(indices = {@Index(value = {"first_name", "last_name"},
        unique = true)})
class User {
    @PrimaryKey
    public int id;

    @ColumnInfo(name = "first_name")
    public String firstName;

    @ColumnInfo(name = "last_name")
    public String lastName;

    @Ignore
    Bitmap picture;
}

注解的 Kotlin 等价物如下:

@Entity(indices = [Index(value = ["first_name", "last_name"], unique = true)])

在您的代码中,您可以进行以下更改以具有唯一约束

@Entity(foreignKeys ={
        @ForeignKey(entity = Label.class, parentColumns = "_id", childColumns = "labelId", onDelete = CASCADE),
        @ForeignKey(entity = Task.class, parentColumns = "_id", childColumns = "taskId", onDelete = CASCADE)},
        indices = {@Index(value = {"labelId", "taskId"},
                unique = true)}
)
public class LabelOfTask extends Data{
    @ColumnInfo(name = "labelId")
    private Integer labelId;
    @ColumnInfo(name = "taskId")
    private Integer taskId;
}

【讨论】:

  • 将单个属性设置为 UNIQUE 怎么样?
  • 我试图回答你的问题,但我认为我粘贴在错误的地方:) 请在下面查看:D
  • 嗨!如果您尝试添加第二个相同的值会怎样?
  • 对于 Kotlin 你可以这样写:foreignKeys = [ForeignKey( entity = Label::class, parentColumns = ["_id"], childColumns = ["labelId"], onDelete = ForeignKey.CASCADE )], indices = [Index(value = ["labelId", "taskId"], unique = true)]
  • 这是使用两列(first_name,last_name)创建复合唯一键的示例吗?还是使用两个不同的列创建两个单独的唯一键的示例??
【解决方案2】:

对于单列唯一性

@Entity(indices = {@Index(value = {"first_name"},unique = true)})

对于多列唯一性

@Entity(indices = {@Index(value = {"first_name", "last_name"},unique = true)}) 

【讨论】:

    【解决方案3】:

    如果你想使单个列唯一,只需要写

    @Entity(indices = [Index(value = ["name"], unique = true)])
    

    【讨论】:

    • 如何创建复合唯一键和复合主键??
    • @KPradeepKumarReddy 在实体注释中有一个 primaryKeys 字段
    猜你喜欢
    • 1970-01-01
    • 2018-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-10
    相关资源
    最近更新 更多