室:@Embedded与@TypeConverters

时间:2020-11-08 11:07:39

标签: java android kotlin android-room

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

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

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

实际上是一个问题:

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

2 个答案:

答案 0 :(得分:1)

实际的区别是@TypeConverter使用相同的表,而@Embedded使用单独的表。即使可以滥用@TypeConverter来对JSON进行序列化/反序列化,这也仅在不需要在那里查询值的情况下才有意义-但是,只要您要查询该数据,就省去了很多工作,当它由一个实际的表支持时,可以对其运行SQL(而不是遍历所有记录并解码JSON)。 JSON实际上是一种数据格式,而不是数据类型。

仅以WordPress post-meta为例...这也是存储在SQL数据库中的JSON。同样,这在技术上是可行的,但这是性能低于标准水平的原因。

正确使用@TypeConverter例如从String转换为BigDecimal

答案 1 :(得分:1)

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

实际上,这里还有另外一种方法需要提及-将复杂对象保存在单独的表中,并使用外键(通常是idInt类型,通常是自动生成的。

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