Room Persistence Library 没有 "NOT NULL" 和 "UNIQUE" 约束
No "NOT NULL" and "UNIQUE" constraint on Room Persistence Library
在使用 Room Persistence Library 时,我了解到没有任何方法可以设置具有 NOT NULL 和 UNIQUE 约束的数据 class 字段。 SQLite 是否支持这些约束。迁移使用这些约束的旧数据库不是问题吗?任何人都可以就此问题提出建议吗?
I came to know that there is no methodology to set a data class field with NOT NULL and also UNIQUE constraints
@Entity
字段上的 @NonNull
注释将导致该字段的列应用 NOT NULL
。
unique=true
在 @Index
上将强制执行唯一性约束(例如,@Entity(indices={@Index(value="something", unique=true)}
)。但是,您是正确的,不支持对列的普通 UNIQUE
约束,而不是通过索引。
Isn't it a problem to migrate old database where those constraints are used?
房间的设计不支持现有的数据库结构,尤其是在现在的 alpha
状态下。随着时间的推移,我希望 Room 支持更高百分比的 SQLite 功能,但如果它达到 100%,我会感到震惊。
关于 NOT NULL
使用 Kotlin 的人的补充回答:
请注意,将类型标记为非可选类型会自动使其不为空(可选类型不会这样做)。
您可以在数据库中使用 @Database(exportSchema = true)
的房间生成的架构中查看它。
例如我有这样的东西:
@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`))"
(注意:这里的 Date 类型是 Int
而 UUID 是字符串,因为我在别处使用了转换器)
如果您有多个要标记为唯一的项目并基于您要插入数据库的项目,那么您可以使用复合主键。
对于 Not null,Room 提供了添加在不能为 null 的字段上的“@NonNull”注释。
在下面提到的例子中。每个 class 中的卷号都是唯一的,但 2 个不同的 class 可以具有相同的卷号。所以我们可以使用 class & rollNumber 作为复合主键并唯一地插入到数据库中。
示例:
@Entity(primaryKeys = {"rollNumber", "class"})
class Student {
@NonNull
private int rollNumber;
private String firstName;
private String lastName;
private int class;
}
对于可为空的字段,您可以使用包装器原始类型 java。例如在你的 Room Table 中使用 Integer instance int。
如在 wrapper primitive type java 中,这可以是空的,但原始类型 class 不能是空的。并且在为使用 notNull=true 的原始字段生成此 SQL 代码时,但在 generayion SQL 代码中使用 Integer 时使用 notNull=false
在使用 Room Persistence Library 时,我了解到没有任何方法可以设置具有 NOT NULL 和 UNIQUE 约束的数据 class 字段。 SQLite 是否支持这些约束。迁移使用这些约束的旧数据库不是问题吗?任何人都可以就此问题提出建议吗?
I came to know that there is no methodology to set a data class field with NOT NULL and also UNIQUE constraints
@Entity
字段上的 @NonNull
注释将导致该字段的列应用 NOT NULL
。
unique=true
在 @Index
上将强制执行唯一性约束(例如,@Entity(indices={@Index(value="something", unique=true)}
)。但是,您是正确的,不支持对列的普通 UNIQUE
约束,而不是通过索引。
Isn't it a problem to migrate old database where those constraints are used?
房间的设计不支持现有的数据库结构,尤其是在现在的 alpha
状态下。随着时间的推移,我希望 Room 支持更高百分比的 SQLite 功能,但如果它达到 100%,我会感到震惊。
关于 NOT NULL
使用 Kotlin 的人的补充回答:
请注意,将类型标记为非可选类型会自动使其不为空(可选类型不会这样做)。
您可以在数据库中使用 @Database(exportSchema = true)
的房间生成的架构中查看它。
例如我有这样的东西:
@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`))"
(注意:这里的 Date 类型是 Int
而 UUID 是字符串,因为我在别处使用了转换器)
如果您有多个要标记为唯一的项目并基于您要插入数据库的项目,那么您可以使用复合主键。
对于 Not null,Room 提供了添加在不能为 null 的字段上的“@NonNull”注释。
在下面提到的例子中。每个 class 中的卷号都是唯一的,但 2 个不同的 class 可以具有相同的卷号。所以我们可以使用 class & rollNumber 作为复合主键并唯一地插入到数据库中。 示例:
@Entity(primaryKeys = {"rollNumber", "class"})
class Student {
@NonNull
private int rollNumber;
private String firstName;
private String lastName;
private int class;
}
对于可为空的字段,您可以使用包装器原始类型 java。例如在你的 Room Table 中使用 Integer instance int。 如在 wrapper primitive type java 中,这可以是空的,但原始类型 class 不能是空的。并且在为使用 notNull=true 的原始字段生成此 SQL 代码时,但在 generayion SQL 代码中使用 Integer 时使用 notNull=false