Android 房间中没有转换器的 Kotlin 可空类型?

Kotlin's Nullable types in Android Room without Converters?

我正在关注此 guide 以了解有关 Android 房间的更多信息。本指南将此示例与可空字符串一起使用。

@Entity
data class User(
    @PrimaryKey val uid: Int,
    @ColumnInfo(name = "first_name") val firstName: String?,
    @ColumnInfo(name = "last_name") val lastName: String?
)

我尝试了自己的示例,但将可为空的字符串替换为可为空的字符串 UInt,结果出现错误“无法弄清楚如何将此字段保存到数据库中。”该错误还表明我使用了类型转换器。但问题是可空性还是整数的无符号性? 更一般地说,是否有关于 @Entity 数据 类 中允许哪些类型的指南?

Room 有一组有限的类型,它知道在存储和检索值时如何直接处理这些类型。其他类型必须分解为这些类型或转换为此类。

More generally is there a guide on what types are allowed in the @Entity data classes?

可以直接处理的类型有:-

  • 空,

  • 布尔型、短整型、整型、长整型、字节(SQLite 类型 INTEGER)

  • 字符串、字符(SQLite 类型文本)

  • 双精度浮点型(SQLite 类型 REAL)

  • 字节[](SQLite 类型 BLOB)

    • SQLite 确实有一个 NUMERIC 类型,但这更像是一个包罗万象的类型。

如您所见,null 是一种有效类型,尽管 Room 不接受主键列(SQLite 确实接受)或(我相信)外键列的 null。

因此,当您使用 UInt Room 时,它会说它不知道如何处理类型,并且需要 TypeConverters 才能转换 to/from UInt。

But is the issue with nullability or with the unsigned-ness of integers? Neither. An SQLite INTEGER can be up to 64bits (signed), so is more than capable of holding any UInt "The kotlin.UInt is an unsigned 32-bit integer (0 to 2^32 – 1)" and actually any ULong "The kotlin.ULong is an unsigned 64-bit integer (0 to 2^64 -1)".

问题实际上是 SQLite 的用途的局限性,也许是 Room 是关于保存对象的误解,而它是关于提供面向对象的方法来在 SQLite 数据库中保存数据。

例如,考虑:-

@Entity
data class CoinEntity(

    @PrimaryKey
    val coinId: String,
    val sshort: Short = 0,
    val sbool: Boolean = true,
    val sbyte: Byte = 1,
    val sint: Int = 0,
    val slong: Long = 0,
    val sstring: String? = null,
    val schar: Char = 'a',
    val sfloat: Float = 0.0F,
    val sdouble: Double = 0.0,
    val sbytearray: ByteArray = byteArrayOf(0b0,0x0)
)

房间将生成以下内容以创建 table :-

_db.execSQL("CREATE TABLE IF NOT EXISTS `CoinEntity` (`coinId` TEXT NOT NULL, `sshort` INTEGER NOT NULL, `sbool` INTEGER NOT NULL, `sbyte` INTEGER NOT NULL, `sint` INTEGER NOT NULL, `slong` INTEGER NOT NULL, `sstring` TEXT, `schar` INTEGER NOT NULL, `sfloat` REAL NOT NULL, `sdouble` REAL NOT NULL, `sbytearray` BLOB NOT NULL, PRIMARY KEY(`coinId`))");

除了 sstring 列之外的所有列都具有 NOT NULL 隐含,即 ? 允许空值,因此 NOT NULL 被省略。