31

我的数据类看起来像这样

@Entity(tableName = "items")
data class Item(
        @ColumnInfo(name = "name") var name: String = "",
        @ColumnInfo(name = "room") var room: String = "",
        @ColumnInfo(name = "quantity") var quantity: String = "",
        @ColumnInfo(name = "description") var description: String = "",
        @PrimaryKey(autoGenerate = true)
        @ColumnInfo(name = "id") var id: Long = 0
)

Room 使用 SQLite,SQLite 在其数据库中支持 NOT NULL 列。我尝试使用 @NonNull 注释列,但没有效果。

有没有办法使房间数据库中的列不能为空?

4

5 回答 5

44

对于 Java,您应该使用@android.support.annotation.NonNull

不要混淆@io.reactivex.annotations.NonNull

于 2017-11-04T09:39:22.717 回答
31

为了确定 NOT NULL 的确切注释,我浏览了此链接提供的所有注释列表:android.arch.persistence.room但找不到任何相关注释:

在此处输入图像描述

我的假设是,由于您使用的是 Kotlin,它默认将 var 视为非可选的,因此您声明的所有属性都不是 NULL。为了将 var 声明为可选,您可能必须使用 ? 运算符,以下示例:

var name: String // NOT NULL 
var name: String? // OPTIONAL

根据评论更新:

我猜你对 NULL 和空字符串感到困惑。NULL 表示没有值,在共享代码中,您为每个列提供了一个默认值,该列是一个空字符串并且不等于 NULL,因此即使您可能没有为该属性提供值,它默认分配一个给它的空字符串。

尝试删除属性的赋值运算符和 RHS 值,然后插入记录而不为该属性分配值,您应该会得到适当的错误。

基本上,转换以下语句:

@ColumnInfo(name = "name") var name: String = ""

@ColumnInfo(name = "name") var name: String
于 2017-06-07T13:07:36.910 回答
12

@NonNull对于我在之后使用的Java @ColumnInfo

@ColumnInfo(name = "column_name")
@NonNull private String str;

确保您在类中导入了正确的库:

import android.support.annotation.NonNull;
于 2018-01-18T19:22:21.137 回答
11

使用 Kotlin 的人的补充答案:

请注意,将类型标记为非可选将自动使其不为空(可选类型不会这样做)。

@Database(exportSchema = true)您可以在数据库上的 room with 生成的模式中检查它。

例如我有这样的事情:

@Entity(tableName = "messages")
data class Message (
        @PrimaryKey
        val messageId: UUID = UUID.randomUUID(),
        val date: Date = Date(),
        val receivedDate: Date? = null
)

在生成的模式中,我可以阅读:

"CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (
    `messageId` TEXT NOT NULL, 
    `date` INTEGER NOT NULL, 
    `receivedDate` INTEGER, 
    PRIMARY KEY(`messageId`)
)"

Int(注意:由于我在其他地方使用的转换器,这里的日期类型是一个,而 UUID 是一个字符串)

于 2017-12-13T06:10:43.080 回答
5

作为解决实际表约束的方法,您可以使用单个方法 TypeConverter 类来确保您的 String 成员不为空。

例如,对于非空字符串,您可以使用:

public class RoomConverterNullString {
    @TypeConverter
    public static String fromNullToString(String value) {
        if (value == null) {
            return "";
        } else {
            return value;
        }
    }
}

当然,您可以像这样简化它:

public class RoomConverterNullString {
    @TypeConverter
    public static String fromNullToString(String value) {
        return (value == null) ? "" : value;
    }
}

你可以像这样使用它:

@TypeConverters(RoomConverterNullString.class)
public String stringMember;

当值为空时,任何赋值和更新/插入操作都将存储一个空字符串值,并且任何检索都会强制将空值转换为空字符串。

您可以对其他类型以及您希望拥有的任何默认值执行此操作。

于 2017-10-19T21:12:59.680 回答