我开始学习房间,我面临着一个问题:
给定两个类,一个是Car,另一个是Car中的Engine。
@Entity
class Car{
@PrimaryKey
var id = 0
var name: String? = null
var engine: Engine? = null
}
...
@Entity
class Engine{
@PrimaryKey
var id = 0
var manufacturer: String? = null
}
我还将这些类初始化为AppDatabase类中的表。
@Database(entities = [Car::class, Engine::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
//...
}
问题是每当我只想运行项目时,我会收到以下错误消息,指向Car的引擎字段:
Cannot figure out how to save this field into database. You can consider adding a type converter for it.
没有简单的方法吗?我正在寻找用最少的代码来保存数据的工具,比如Firestore,它可以用简单的注解来完成所有的工作。
先谢了。
2条答案
按热度按时间hm2xizp91#
因为一辆车只有一个发动机,你有一个发动机表和一个汽车表,那么你有一个一对多的关系,也就是说一辆车可以有一个发动机,但是同一个发动机可以被很多汽车使用。
因此,与其试图将引擎嵌入到汽车中,不如建立一个关系,汽车(子)引用引擎(父)。
这就像将汽车更改为:-
另一种不需要关系也不需要TypeConverter的方法是不将Engine作为表,而是在Engine之前使用@Embedded注解。
...
@Entity
注解,因为您将Engine值存储在Car中。从数据库的Angular 来看,第三种也是最不可取的方法是将引擎对象的表示形式存储在单列中。也就是说,将对象转换为单一的可存储表示形式。通常是JSON字符串。因此,您需要代码(一个函数)将对象转换为单个值(JSON字符串),并需要代码(另一个函数)将JSON字符串转换为对象。
使用这种方法,不仅不能规范化数据,而且最终存储了表示对象所需的膨胀,从数据库的Angular 来看,这种膨胀在某种程度上混淆了实际有用的存储数据。
此外,没有一个集合/标准库提供将对象转换为JSON或从JSON转换对象的功能,因此您必须选择一种风格,然后将该库包含在项目中。
下面是一个类,其中包含可以使用的类型转换器(请参阅库的注解):-
这将适合您原来的类。
需要通过@TypeConverters注解(注意是复数而不是单数)告知Room使用这些类(它会计算出何时使用),这是在@Database注解具有最高级别作用域之前或之后立即使用的。
为了一起演示所有这三个方面,请考虑顶级Car类:-
**引擎 * 类
类型转换器如上所述。
准备好上述内容并在活动中使用后(请注意,为了简洁/方便起见,使用了.allowMainThreadQueries):-
使用Android Studios应用程序检查查看数据库,然后
引擎表(仅关系需要)为:-
cxfofazt2#
您应该使用类型转换器:
1.首先,将此依赖项添加到项目中以将Engine转换为Json,反之亦然
实现“com.squareup.retrofit2:转换器-gson:2.5.0”
1.现在,您应该创建一个Object类,将Engine转换为Json。该类使Engine对于Room来说是可理解的:
最后,Engine不是一个实体,您应该在数据库类中添加@Typeconverter注解: