Android Room中如何使用单个模型适配多个相同结构的实体?
可实现同结构多实体的复用方案
完全可以通过公共基类抽离的方式消除重复的实体代码,这也是Room框架下实现同结构多表实体复用的最优方式,能最大程度减少重复代码,同时保留Room完整的字段映射、编译期校验能力。
具体实现方式
- 第一步:抽离不带任何Room注解的公共基类,把两个实体完全重复的字段、通用逻辑全部迁移到基类中:
// 纯公共父类,不添加任何Room注解,不会被识别为独立实体参与数据库结构生成 public class BaseDictionaryEntry { @PrimaryKey protected Integer id = null; @NonNull protected String word = ""; @NonNull protected String translation = ""; @NonNull protected String related_words = ""; // 两个实体通用的工具逻辑可以直接写在这里,无需重复实现 public String getDisplayWord() { return word.trim(); } } - 第二步:两个对应不同表的实体类直接继承这个公共基类,仅保留@Entity注解和独立的表名声明即可,不需要重复编写任何重复字段:
@Entity(tableName = "eng_dictionary") public class EnglishDictionary extends BaseDictionaryEntry { // 继承自父类的所有字段,Room会自动识别完成列映射,和单独在子类编写字段的映射效果完全一致 } @Entity(tableName = "krn_dictionary") public class KoreanDictionary extends BaseDictionaryEntry { // 无重复字段代码 }
必须留意的规则
- 公共基类不能添加任何Room相关注解,比如不能给基类加上@Entity注解,否则Room会把这个基类识别为独立实体,自动生成一张无意义的额外表,直接触发编译错误。
- 继承得到的字段映射规则和直接在子类编写字段完全一致:默认列名和字段名保持一致;如果后续需要单独调整某一张表的列名、索引规则,只需要在对应的子类中重写字段,搭配@ColumnInfo、@Index等注解单独配置即可,不会影响另一张表的映射规则。
- 这种方式已经是Room框架下的重复度最低实现:Room本身要求每一张数据库表必须对应一个独立的、带@Entity注解的实体类,无法通过单个带@Entity的类同时映射两张结构相同的表,因此必须保留两个独立的子类类声明,除此之外的所有重复代码都可以通过继承抽离完成复用。
额外的复用空间
因为两个实体的结构完全一致,后续你可以基于公共基类抽离通用的处理逻辑,比如批量词条的格式化、内容合法性校验等,不需要在两个实体类中重复实现完全相同的方法。
内容的提问来源于stack exchange,提问作者Hamizul Fuad
相关产品推荐
相关产品推荐

