如何生成适合我的房间方案的数据库?
How can I generate a DB, that fits my room scheme?
我有一个包含很多实体的数据库,我想在第一次创建数据库时从文件中预加载数据。为此,Room 的方案需要适合数据库文件的方案。由于手动将 json 方案转换为 SQLite 语句非常容易出错(我需要复制粘贴每一个语句并交换变量名)我正在寻找一种可能性来自动从该方案生成一个数据库,然后我只需要填充数据。
然而,显然在互联网上没有关于这是否可能的信息,甚至没有关于如何这样做的信息。这是我第一次使用 SQLite(通常我使用 MySQL),也是我第一次在 json 中看到数据库方案。 (因为标准的 MariaDB 导出选项总是只导出 CREATE TABLE 语句。)
有办法吗?或者 Room 是否提供了实际获取 create table 语句作为适当文本的方法,而不是拆分成大量 JSON 数组?
我按照 Android 开发人员指南上的指南获得了 json 方案,所以我已经有了那个文件。对于那些不知道它的结构的人,它看起来像这样:
{
"formatVersion": 1,
"database": {
"version": 1,
"identityHash": "someAwesomeHash",
"entities": [
{
"tableName": "Articles",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `germanArticle` TEXT NOT NULL, `frenchArticle` TEXT, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "germanArticle",
"columnName": "germanArticle",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "frenchArticle",
"columnName": "frenchArticle",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": false
},
"indices": [
{
"name": "index_Articles_germanArticle",
"unique": true,
"columnNames": [
"germanArticle"
],
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Articles_germanArticle` ON `${TABLE_NAME}` (`germanArticle`)"
},
{
"name": "index_Articles_frenchArticle",
"unique": true,
"columnNames": [
"frenchArticle"
],
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Articles_frenchArticle` ON `${TABLE_NAME}` (`frenchArticle`)"
}
],
"foreignKeys": []
},
...
注意:我的问题不是,如何从方案中创建 Room DB。要接收方案,我已经必须创建所有实体和数据库。但是如何让 Room 创建为 SQL 的结构来预填充我的数据库。但是,我认为答案是一个很好的解释,事实上我在生成的 Java 文件中找到了我正在搜索的 SQL-Statements,这是一个很棒的提示。 ;)
Is there a way? Or does Room provide anyway to actually get the create table statements as a proper text, not split up in tons of JSON arrays?
您不能简单地为 Room 提供 CREATE SQL,您需要做的是从 JSON 生成 java/Kotlin classes(实体)和然后将这些 classes 添加到项目中。
- 原生 SQLite(即不使用 Room)将是另一回事,因为它可以在运行时完成。
Room 的工作方式是,数据库是从 class 注释的 @Entity
中生成的(在编译时)。
Entity/classes 必须存在,编译才能正确生成它生成的代码。
此外,实体必须 incorporated/included 变成数据库的 class,用 @Database
注释(这个 class 通常是抽象的) .
此外,要访问数据库 tables,您有 SQL 的抽象 classes 或接口,每个都用 @Dao 注释,并且再次需要实体 classes 因为 SQL 在编译时被检查。
例如您提供的 JSON 等同于:-
@Entity(
indices = {
@Index(value = "germanArticle", name = "index_Articles_germanArticle", unique = true),
@Index(value = "frenchArticle", name = "index_Articles_frenchArticle", unique = true)
}
, primaryKeys = {"id"}
)
public class Articles {
//@PrimaryKey // Could use this as an alternative
long id;
@NonNull
String germanArticle;
String frenchArticle;
}
- 因此您的流程必须转换 JSON 以创建上述内容,然后可以将其复制到项目中。
然后您需要一个 Class 数据库,例如:-
@Database(entities = {Articles.class},version = 1)
abstract class MyDatabase extends RoomDatabase {
}
请注意,Dao classes 将按照 :-
添加到上面的正文中
abstract MyDaoClass getDao();
Or does Room provide anyway to actually get the create table statements as a proper text, not split up in tons of JSON arrays?
是的 ....
在这个阶段,如果你编译它会生成 java(上面的 MyDatabase_Impl 即数据库的名称 class 后缀为 _Impl
)。但是因为没有道classes/interfaces。从 Room 的角度来看,数据库将不可用(因此甚至不会创建)。
生成的部分代码将是:-
@Override
public void createAllTables(SupportSQLiteDatabase _db) {
_db.execSQL("CREATE TABLE IF NOT EXISTS `Articles` (`id` INTEGER NOT NULL, `germanArticle` TEXT NOT NULL, `frenchArticle` TEXT, PRIMARY KEY(`id`))");
_db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS `index_Articles_germanArticle` ON `Articles` (`germanArticle`)");
_db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS `index_Articles_frenchArticle` ON `Articles` (`frenchArticle`)");
_db.execSQL("CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)");
_db.execSQL("INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'f7294cddfc3c1bc56a99e772f0c5b9bb')");
}
- 如您所见,文章 table 和两个索引已创建,room_master_table 用于验证检查。
我有一个包含很多实体的数据库,我想在第一次创建数据库时从文件中预加载数据。为此,Room 的方案需要适合数据库文件的方案。由于手动将 json 方案转换为 SQLite 语句非常容易出错(我需要复制粘贴每一个语句并交换变量名)我正在寻找一种可能性来自动从该方案生成一个数据库,然后我只需要填充数据。 然而,显然在互联网上没有关于这是否可能的信息,甚至没有关于如何这样做的信息。这是我第一次使用 SQLite(通常我使用 MySQL),也是我第一次在 json 中看到数据库方案。 (因为标准的 MariaDB 导出选项总是只导出 CREATE TABLE 语句。) 有办法吗?或者 Room 是否提供了实际获取 create table 语句作为适当文本的方法,而不是拆分成大量 JSON 数组? 我按照 Android 开发人员指南上的指南获得了 json 方案,所以我已经有了那个文件。对于那些不知道它的结构的人,它看起来像这样:
{
"formatVersion": 1,
"database": {
"version": 1,
"identityHash": "someAwesomeHash",
"entities": [
{
"tableName": "Articles",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `germanArticle` TEXT NOT NULL, `frenchArticle` TEXT, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "germanArticle",
"columnName": "germanArticle",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "frenchArticle",
"columnName": "frenchArticle",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": false
},
"indices": [
{
"name": "index_Articles_germanArticle",
"unique": true,
"columnNames": [
"germanArticle"
],
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Articles_germanArticle` ON `${TABLE_NAME}` (`germanArticle`)"
},
{
"name": "index_Articles_frenchArticle",
"unique": true,
"columnNames": [
"frenchArticle"
],
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Articles_frenchArticle` ON `${TABLE_NAME}` (`frenchArticle`)"
}
],
"foreignKeys": []
},
...
注意:我的问题不是,如何从方案中创建 Room DB。要接收方案,我已经必须创建所有实体和数据库。但是如何让 Room 创建为 SQL 的结构来预填充我的数据库。但是,我认为答案是一个很好的解释,事实上我在生成的 Java 文件中找到了我正在搜索的 SQL-Statements,这是一个很棒的提示。 ;)
Is there a way? Or does Room provide anyway to actually get the create table statements as a proper text, not split up in tons of JSON arrays?
您不能简单地为 Room 提供 CREATE SQL,您需要做的是从 JSON 生成 java/Kotlin classes(实体)和然后将这些 classes 添加到项目中。
- 原生 SQLite(即不使用 Room)将是另一回事,因为它可以在运行时完成。
Room 的工作方式是,数据库是从 class 注释的 @Entity
中生成的(在编译时)。
Entity/classes 必须存在,编译才能正确生成它生成的代码。
此外,实体必须 incorporated/included 变成数据库的 class,用 @Database
注释(这个 class 通常是抽象的) .
此外,要访问数据库 tables,您有 SQL 的抽象 classes 或接口,每个都用 @Dao 注释,并且再次需要实体 classes 因为 SQL 在编译时被检查。
例如您提供的 JSON 等同于:-
@Entity(
indices = {
@Index(value = "germanArticle", name = "index_Articles_germanArticle", unique = true),
@Index(value = "frenchArticle", name = "index_Articles_frenchArticle", unique = true)
}
, primaryKeys = {"id"}
)
public class Articles {
//@PrimaryKey // Could use this as an alternative
long id;
@NonNull
String germanArticle;
String frenchArticle;
}
- 因此您的流程必须转换 JSON 以创建上述内容,然后可以将其复制到项目中。
然后您需要一个 Class 数据库,例如:-
@Database(entities = {Articles.class},version = 1)
abstract class MyDatabase extends RoomDatabase {
}
请注意,Dao classes 将按照 :-
添加到上面的正文中abstract MyDaoClass getDao();
Or does Room provide anyway to actually get the create table statements as a proper text, not split up in tons of JSON arrays?
是的 ....
在这个阶段,如果你编译它会生成 java(上面的 MyDatabase_Impl 即数据库的名称 class 后缀为 _Impl
)。但是因为没有道classes/interfaces。从 Room 的角度来看,数据库将不可用(因此甚至不会创建)。
生成的部分代码将是:-
@Override
public void createAllTables(SupportSQLiteDatabase _db) {
_db.execSQL("CREATE TABLE IF NOT EXISTS `Articles` (`id` INTEGER NOT NULL, `germanArticle` TEXT NOT NULL, `frenchArticle` TEXT, PRIMARY KEY(`id`))");
_db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS `index_Articles_germanArticle` ON `Articles` (`germanArticle`)");
_db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS `index_Articles_frenchArticle` ON `Articles` (`frenchArticle`)");
_db.execSQL("CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)");
_db.execSQL("INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'f7294cddfc3c1bc56a99e772f0c5b9bb')");
}
- 如您所见,文章 table 和两个索引已创建,room_master_table 用于验证检查。