如何在Android Room实体中注释默认值?

42

在查看新的Android Persistence Library的@ColumnInfo文档时,我找不到有关如何注释SQL中“DEFAULT”值的任何信息。

Room是否提供用于默认值的注释?

我的当前解决方案是手动创建相应的表...

CREATE TABLE MyTable (
  ...
  MyDefaultValuedCol  TEXT DEFAULT 'Default Value',
  MyDefaultFlagCol    INT  DEFAULT 1
)

...并将Room放在最上面。

@Entity(tableName = "MyTable")
class MyClass {
    ...

    public String MyDefaultValuedCol;

    public boolean MyDefaultFlagCol;

}
5个回答

46

随着 room persistence 2.2.0 版本的发布,@ColumnInfo 注解中新增了一个属性,可以用于指定列的默认值。详见文档

@Entity(tableName = "users")
data class User(
    @PrimaryKey val id: Long,
    @ColumnInfo(name = "user_name", defaultValue = "temp") val name: String
    @ColumnInfo(name = "last_modified", defaultValue = "CURRENT_TIMESTAMP" ) val lastModified: String
)

3
谢谢提到这个问题。但是我们可以把布尔值(true/false)设置为默认值吗?我尝试了一下,但是出现了错误。 @ColumnInfo(name = "is_deleted", defaultValue = false) var is_deleted:Boolean, 布尔字面量不符合预期的字符串类型。 - Qadir Hussain
2
@Qadir,虽然我没有尝试过,但我相信Room将布尔值存储为整数。 假设是这种情况,根据https://developer.android.com/reference/androidx/room/ColumnInfo.html#defaultValue(),您应该能够将defaultValue =“0”设置为false。 - Bink
2
请注意,在此处指定的默认值将不会在您仅使用 /@Insert 插入实体时使用。在这种情况下,将使用在 Java/Kotlin 中分配的任何值。使用 /@Query 与 INSERT 语句,并跳过该列以便使用此默认值。 - Patriotic
3
@QadirHussain 房间实际上将布尔值存储为“0”(false)或“1”(true)。您需要将布尔列的默认值设置为其中之一。 - Trex

10

Room没有默认值的注释,但您可以在实体中像这样设置默认值:

@Entity(tableName = "MyTable")
class MyClass {
    ...

    public String MyDefaultValuedCol = "defaultString";

    public boolean MyDefaultFlagCol = true;

}

8
请记住,这不会修改生成的SQLite表格创建以设置默认值。 - tasomaniac
5
当您直接执行语句(例如仅更新某些字段)时,这并没有帮助。我们需要能够在 SQL 中生成默认值。 - Brill Pappin

10
您可以使用@ColumnInfo注释设置默认值 -
@ColumnInfo(defaultValue = "No name")
public String name;

并且

@ColumnInfo(defaultValue = "0")
public int flag;

或任何数据类型,可以在此处查看参考资料 Google 开发者文档


@Ahsan Saeed的回答很好,但我认为这个稍微更好,因为它显示你仍然需要在数字字段中使用字符串。这对于浮点数也适用,似乎不需要在数字之后加上L。 - rminaj

3

你可以在实体的getter方法中检查并设置一些默认值。

@Entity(tableName = "Dashboard")
public class Dashboard {
@PrimaryKey
@NonNull
@ColumnInfo(name = "claimNumber")
private String claimNumber;
private String percentage = "0";
private String imagePath = "";

@NonNull
public String getClaimNumber() {
    return claimNumber;
}

public void setClaimNumber(@NonNull String claimNumber) {
    this.claimNumber = claimNumber;
}



public String getPercentage() {
    if (percentage == null || percentage.isEmpty()) {
        return "0";
    }
    return percentage;
}

public void setPercentage(String percentage) {
    this.percentage = percentage;
}

public String getImagePath() {
    return imagePath;
}

public void setImagePath(String imagePath) {
    this.imagePath = imagePath;
}

public Dashboard(@NonNull String claimNumber,  String percentage, String imagePath) {
    this.claimNumber = claimNumber;

    this.percentage = percentage;
    this.imagePath = imagePath;
}

}


将数字值表示为数据类型“String”的意义是什么? - Martin Zeitler
将数字值表示为字符串是没有意义的。我只是举个例子。@MartinZeitler - Patel Jaimin

0

对于任何遇到以下情况的人,即当您有两个外键且“onDelete = CASCADE”时,您可以将外键设置为可以设置为空的数据类型,例如:

int parent1Id = 0;
int parent2Id = 0;  
//should be:
Long parent1Id = null;
Long parent2Id = null;

这样数据库就知道在尝试删除父级时,特定的对象/行没有其他不同类型的父级。


为什么不用 Integer 呢? - Tobiq
1
由于插入操作将返回一个长整型的ID,最好使用Long类型。 - Amr Berag

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接