房间:@Embedded 与 @TypeConverters

Ser*_*aka 7 java android kotlin android-room

如果我们在 Room 中有 @Entity,其中有复杂的对象作为字段,我们可以使用 2 种方法:

@Embedded - 据我了解,如果您使用此注释标记字段,则 Room 会将对象内部的所有字段保存为实体本身的字段,然后正确检索所有内容。

@TypeConverters - 在这里我们编写自己的转换器,在大多数情况下可以归结为将对象通常解析为 Json 字符串。

其实问题是:

根本的区别是什么?为什么不到处写@Embedded而不用担心转换器呢?什么时候最好编写自己的转换器,什么时候最好使用@Embedded,这些方法的优点和缺点是什么?

ser*_*nov 3

如果我们在 Room 中有 @Entity,其中有复杂的对象作为字段,我们可以使用 2 种方法

实际上,这里还有一种方法要提到 - 将复杂对象保存在单独的表中,并使用外键链接到它(与通常id使用IntorLong类型一样,通常是自动生成的)。

  • 如果复杂对象有自己的值并且与其他对象有多个连接,请考虑使用单独的表和外键。示例:您有复杂的对象User和另一个对象 - UserGroup(和字段:)userDocument(字段author:)。使用单独的表,User您只能在一个地方更改用户名,并且不需要触摸其他两个表(但您应该使用@Embedded方法来做到这一点)。
  • -的广泛使用用例Type-converter是将类型转换Date为整数,因为 Sqlite 不知道如何使用其自己的类型系统来保存此类型。@Embedded在这种情况下没有帮助。
  • 另一个广泛使用的用例Type-converter是持久保存数据库复杂的嵌套结构,通常从后端 API(JSON 序列化)获取。但是,如果您稍后决定独立处理这些嵌套结构的一部分(例如,对它们进行查询),则这种方法很脆弱。
  • 一种更广泛使用(就我的口味而言 - 使用太多)的用例是将Type-converter某些对象的列表或数组保留在一个字段中。但通常可以使用单独的表和外键来替换这种方法(如果构成列表的这些对象有其自己的值)。
  • 如果在同一个复杂对象上使用多个@Entity,@Embedded则表明您应该考虑使用单独的表和外键的选项,因为它浪费空间,并且在某种程度上违反了数据库表规范化的原则。例如,如果某个复杂对象有 N 个字段,并且您将其用作@Embedded另外两个表中的字段,则意味着 SQLite 在这两个表中生成 N 个附加列。
  • 应该提到的是,@Embedded@Relation 广泛用于 Room 的数据类(ROOM 的 JOIN 类似物)。它们确实很有帮助,并且有助于保持这些数据类的代码简短。这样,@Embedded 不会向表的结构添加任何重复(因为它只影响内存中的对象),就像在用 @Entity 注释的类中使用时那样。