如何在预先填充的数据库中使用Room Persistence Library?

Alb*_*nta 60 android android-sqlite android-room

我想将Room与预先填充的数据库一起使用,但我无法理解如何告诉Room在哪里可以找到我的数据库.

我现在把它放进去src/main/assets/databases,当我为Room数据库创建实例时,我就是这样创建的:

Room.databaseBuilder(
    getApplicationContext(),
    AppDatabase.class,
    "justintrain.db"
)
.allowMainThreadQueries()
.build();
Run Code Online (Sandbox Code Playgroud)

这样,我认为它每次创建一个新的数据库,或者不管怎样,它不使用预先填充的数据库.

我怎样才能找到我的数据库?

Alb*_*nta 36

这就是我解决它的方式,以及如何使用预先填充的数据库发送应用程序(最多为Room v.alpha5)

  • 把你的SQLite DB database_name.db放到assets/databases文件夹中

  • 从这个repo获取文件并将它们放在一个名为ie的包中sqlAsset

  • 在您的AppDatabase班级中,相应地修改会议室的数据库创建代码:

    Room.databaseBuilder(context.getApplicationContext(), 
                         AppDatabase.class, 
                         "database_name.db")
    .openHelperFactory(new AssetSQLiteOpenHelperFactory())
    .allowMainThreadQueries()
    .build();
    
    Run Code Online (Sandbox Code Playgroud)

请注意,您必须使用"database_name.db"和不使用getDatabasePath()或其他方法:它只需要文件的名称.

  • 感谢@Alberto Giunta它节省了我的时间!我使用你的代码并构建依赖,以便在这里使用!https://github.com/daolq3012/AssetSQLiteOpenHelper任何人都可以通过简单的方式使用它. (12认同)
  • 嘿@PedroGuerra!我使用了一个名为"DB Browser for SQLite"的简单程序.我认为它是跨平台的,所以应该能够很好地满足您的需求! (7认同)

Nis*_*nth 20

没有任何其他外部库的简单解决方案

Room依赖于现有的Android框架代码来创建或打开数据库.如果您查看FrameworkSQLiteOpenHelper(Room的版本SQLiteOpenHelper)的源代码,它会在内部调用,SQLiteOpenHelper.getReadableDatabase()并在需要的地方调用其他方法.

因此,最简单的解决方案是mContext.getDatabasePath("my-database.sqlite")在创建具有Room的DB之前,将资产目录中的DB文件复制到资源目录.

在您的情况下,代码看起来像这样 -

private final String DB_NAME = "my-database.sqlite";

private MyDatabase buildDatabase(Context context) {
    final File dbFile = context.getDatabasePath(DB_NAME);

    if(!dbFile.exists()) {
        copyDatabaseFile(dbFile.getAbsolutePath());
    }

    return Room.databaseBuilder(context.getApplicationContext(),
        MyDatabase.class, DB_NAME)
        .build();
}

private void copyDatabaseFile(String destinationPath) {
    // code to copy the file from assets/database directory to destinationPath
}
Run Code Online (Sandbox Code Playgroud)

此链接具有复制DB - 代码所需的代码

  • 非常感谢。这应该是公认的答案。我花了一整天试图解决这个问题。我知道我们不需要另一个库,并且可以将数据库文件复制到数据库位置。 (4认同)

hum*_*zed 16

我遇到了同样的问题所以我创建了一个完全正确的库.接受的答案工作,但我认为使用图书馆更容易.

AppDatabase db = RoomAsset
    .databaseBuilder(context.getApplicationContext(), AppDatabase.class, "database_name.db")
    .build(); 
Run Code Online (Sandbox Code Playgroud)

将其添加到存储库末尾的根build.gradle:

allprojects {
    repositories {
        ...
        maven { url "https://jitpack.io" }
    }
}
Run Code Online (Sandbox Code Playgroud)

添加依赖项

dependencies {
    // ... other dependencies
    implementation 'com.github.humazed:RoomAsset:v1.0'
}
Run Code Online (Sandbox Code Playgroud)

你可以在这里找到这个库:https://github.com/humazed/RoomAsset

  • 这是有风险的。迁移可能不会成功。 (3认同)

Xen*_*ion 9

Room 现在支持预填充数据库。只需使用SQLite 浏览器等程序或您选择的任何其他程序来准备您的数据库。然后把它放在Assets Folder一个名为databasethen的子文件夹中,然后调用:

Room.databaseBuilder(appContext, AppDatabase.class, "Sample.db")
.createFromAsset("database/myapp.db")
.build()
Run Code Online (Sandbox Code Playgroud)

如果您没有将数据库作为资产提供,而是下载了它或者它在文件系统中,那么方法是:

Room.databaseBuilder(appContext, AppDatabase.class, "Sample.db")
.createFromFile(File("mypath"))
.build()
Run Code Online (Sandbox Code Playgroud)

有关此功能的更多描述或数据库迁移,您可以查看文档培训

  • 我刚刚注意到,我的数据库总是被内部资产覆盖(每次启动应用程序时)。难道其他人也遇到过这个问题吗?使用房间2.2.5 (2认同)

Ale*_*drH 7

没有黑客或依赖关系的2019年工作解决方案(Kotlin)

  1. 将您的.db文件放置在assets/databases(或实际上在其中的任何文件夹,只要在下面assets)。

  2. 使用Room 2.2的现有createFromAsset()功能,将其传递到数据库的路径。例如,如果您的数据库文件已命名my_data.db并且位于文件夹的databases目录下assets,则可以这样做createFromAsset("databases/my_data.db")

假设您的数据库名称(例如my_data)存储在名为的常量变量中DATABASE_NAME,则可以使用以下示例代码:

Room.databaseBuilder(
                    context.applicationContext,
                    MyDatabase::class.java,
                    DATABASE_NAME
                )
                    .createFromAsset("databases/$DATABASE_NAME.db")
                    .build()
Run Code Online (Sandbox Code Playgroud)

重要提示:确保数据类/实体的模式与.db文件的模式完全匹配。例如,如果未NOT NULL.db文件中明确标记列,则表示该列中可以包含空值。在Kotlin中,您必须将其与val colName: dataType? = null您的数据类相匹配。如果您只是这样做val colName: dataType,Kotlin会将其编译为一NOT NULL列,并且在您尝试运行您的应用程序时会抛出异常。

注意:如果您想从下载到Android设备本身的数据库文件中创建Room数据库,则可以选择使用该createFromFile()功能。查看有关如何执行此操作的官方文档