如何在Android Room中完全重新创建数据库?

Gre*_*lli 15 android-room

我有一种情况,我希望能够使用Android Room硬重置我的数据库.使用SQLiteOpenHelper,我可以通过编写一个方法来删除所有表和索引,然后手动调用SQLiteOpenHelper.onCreate().

我知道我可以访问一个SupportSQLiteOpenHelper通风室并自己丢弃所有表格,但似乎没有一个好方法来启动娱乐过程.

另外,我知道我可以删除每个表中的每个项目而不删除它,但这不是我想要的.这不会重置自动递增主键,因此新项目的"id"字段不会重置为1.

谢谢!

编辑:
这是我希望能够在运行时任意做的事情.

编辑2:
该方法应该是可维护的,即不涉及手写符合Room行为的SQL.理想情况下,可以通过某种方式检索 Room生成的SQL或SQLiteOpenHelper.onCreate()等效方法.或其他任何解决这个问题的方法!:)

Bin*_*ink 8

我发现最简单的方法是通过context.deleteDatabase(“ name”),然后在首次访问时通过Room.databaseBuilder()。addCallback重新实例化并重新填充数据库。


Jac*_*ton 6

简单的答案是增加您的@Database 版本号。一般来说,您应该对架构更改执行此操作,但是它将实现清除数据库并重置所有主键值的目标。

@Database(entities = { Hello.class }}, version = 1) // <- you want to increase version by 1
@TypeConverters({})
public abstract class AppDatabase extends RoomDatabase {
    public abstract HelloDao helloTextDao();
}
Run Code Online (Sandbox Code Playgroud)

编辑:如果您想在运行时执行此操作,我会清除表中的所有数据(以避免 FK 问题),然后DROP TABLE table_name在所有各自的表上调用 , 。然后您将需要编写查询来创建表,即:CREATE TABLE table_name (uid INTEGER PRIMARY KEY, name STRING);

不幸的是,这意味着您必须维护一个与 POJO 保持同步的创建表查询列表。理想情况下,您可以使用反射来生成查询,但是 @ColumnInfo 目前不支持反射,因为它设置RetentionPolicyCLASS.

希望这能解决您的问题,请随时在评论中要求进一步说明。狩猎快乐!

  • 是的,我相信这将完成应用程序更新之间的任务。但是,我希望能够在运行时任意执行此操作(我可以使用我描述的删除所有表并调用 onCreate() 的“旧”方法来执行此操作)。我更新了我的问题以反映这一点。 (2认同)
  • 嘿,我知道这是一种可能的解决方案。不幸的是,我不认为这是可以接受的。手动编写 SQL 来重新创建 Room 自动生成的内容会导致灾难。微小的差异可能会产生可怕的错误。使用“旧”方法,我可以保证调用 onCreate() 将完全按原样重新创建表。我在这里不能保证这一点。我想我希望我们能够以某种方式访问​​ Room 的等效 onCreate() 方法,或其他一些硬重置方法? (2认同)
  • 我认为数据库版本与代码版本不匹配不是一个好主意。我想避免谈论我的具体用例,但本质上我有一个充当搜索索引的数据库。我想在每次重新创建索引时重置数据库,这可能会很多次。目前,清空表而不重置主键就足够了,但在开发过程中,分析具有一位和两位数 ID 的数据库比分析多位 ID 的数据库要好得多。是的,我有一个特定的(并且发牢骚的)用例,但在我切换到 Room 之前这很容易:) (2认同)