房间持久性库。删除所有

Posted

技术标签:

【中文标题】房间持久性库。删除所有【英文标题】:Room persistance library. Delete all 【发布时间】:2017-10-29 21:09:59 【问题描述】:

如何使用 Room Persistence Library 删除特定表上的所有条目? 我需要删除表,但我找不到任何信息如何执行此操作。

仅当数据库正在迁移或加载所有条目并删除它们时:)

【问题讨论】:

从 Room 1.1.0 开始,您可以使用clearAllTables(),它“从作为实体()注册到此数据库的所有表中删除所有行”。我已将其作为答案包含在下面,但我在这里复制以提高知名度。 【参考方案1】:

您可以创建一个 DAO 方法来执行此操作。

@Dao 
interface MyDao 
    @Query("DELETE FROM myTableName")
    public void nukeTable();

【讨论】:

啊,我没想到。我假设@Query 仅限于返回结果集的东西(类似于rawQuery())。很酷! @yigit 我可以要求@Delete 不带参数并从表中删除所有参数吗?我正在尝试找到 Room 的跟踪器来归档... 当心!至于房间 alpha4 版本,这种技术将导致 gradle 构建失败:issuetracker.google.com/issues/63608092 Ids 怎么样?我确实喜欢这样,但表 ID 继续增加。在真正的表 drop 中,id 也被删除,重新从 0 开始。 @yigit 有没有办法查出查询是成功运行还是出错了?【参考方案2】:

如果想从 Room 中的表中删除一个条目,只需调用此函数,

@Dao
public interface myDao
    @Delete
    void delete(MyModel model);

更新:如果你想删除完整的表,调用下面的函数,

  @Query("DELETE FROM MyModel")
  void delete();

注意:这里的MyModel是一个表名。

【讨论】:

我在使用你的更新代码后得到了这个错误错误:一个抽象的 DAO 方法必须用一个且只有一个以下注解进行注解:Insert,Delete,Query,Update,RawQuery void delete(); 【参考方案3】:

1.1.0 房间开始,您可以使用clearAllTables(),其中:

从作为entities()注册到该数据库的所有表中删除所有行。

【讨论】:

小心:clearAllTables() 是异步的,无法判断它何时完成。 @Alexey 但在 clearAllTables 之后尝试保存某些内容会不会有任何问题?如在,它只会尝试在清除后插入吗?因为我觉得很好。 @FirstOne clearAllTables 基本上只是在新的后台线程上启动事务。它从表中删除所有数据,然后提交该事务。如果您开始交易的时间晚于 clearAllTables 开始,那您很好。话虽如此,如果您尝试在调用 clearAllTable 之后立即插入一些数据,您的插入可能会在 clearAllTable 开始事务之前开始,您将丢失所有数据。如果需要在调用 clearAllTable 后立即插入新数据,至少要增加一些延迟。 @Alexey 有没有办法使用回调方法或类似方法来确定删除事务的状态?换句话说,如果删除事务状态已完成,则继续插入数据方法。 @AJW 不,到目前为止,仍然无法判断操作何时完成。如果你真的需要这个功能,你可能想试试SELECT name FROM sqlite_master WHERE type='table',然后手动DELETE FROM TABLE。不过还没有测试过。【参考方案4】:

结合Dick Lucas 所说的内容并从其他 *** 帖子中添加重置自动增量,我认为这可以工作:

fun clearAndResetAllTables(): Boolean 
    val db = db ?: return false

    // reset all auto-incrementalValues
    val query = SimpleSQLiteQuery("DELETE FROM sqlite_sequence")

    db.beginTransaction()
    return try 
        db.clearAllTables()
        db.query(query)
        db.setTransactionSuccessful()
        true
     catch (e: Exception)
        false
     finally 
        db.endTransaction()
    

【讨论】:

对于它的价值,我发现最简单的方法是通过 context.deleteDatabase(“name”) 执行此操作,然后通过 Room.databaseBuilder().addCallback 重新实例化并重新填充数据库。访问。 什么是 sqlite_sequence?【参考方案5】:

将clearAllTables() 与RXJava 一起使用,如下所示,以避免java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.

Completable.fromAction(new Action() 
        @Override
        public void run() throws Exception 
            getRoomDatabase().clearAllTables();
        
    ).subscribeOn(getSchedulerProvider().io())
            .observeOn(getSchedulerProvider().ui())
            .subscribe(new Action() 
                @Override
                public void run() throws Exception 
                    Log.d(TAG, "--- clearAllTables(): run() ---");
                    getInteractor().setUserAsLoggedOut();
                    getMvpView().openLoginActivity();
                
            , new Consumer<Throwable>() 
                @Override
                public void accept(Throwable throwable) throws Exception 
                    Log.d(TAG, "--- clearAllTables(): accept(Throwable throwable) ----");
                    Log.d(TAG, "throwable.getMessage(): "+throwable.getMessage());


                
            );

【讨论】:

【参考方案6】:

我在使用 RxJava 在后台执行此任务时遇到了删除所有方法的问题。这就是我最终解决它的方法:

@Dao
interface UserDao 
    @Query("DELETE FROM User")
    fun deleteAll()

fun deleteAllUsers() 
    return Maybe.fromAction(userDao::deleteAll)
        .subscribeOn(Schedulers.io())
        .observeOn(androidSchedulers.mainThread())
        .subscribe (
            d("database rows cleared: $it")
        , 
            e(it)
        ).addTo(compositeDisposable)

【讨论】:

当你使用 Kotlin 时,你可以直接将其包裹在 thread 中,而不是使用 RxJava 来搞砸【参考方案7】:

要在不滥用@Query 注释的情况下使用Room,首先使用@Query 选择所有行并将它们放在一个列表中,例如:

@Query("SELECT * FROM your_class_table")

List`<`your_class`>` load_all_your_class();

将他的列表放入delete注解中,例如:

@Delete

void deleteAllOfYourTable(List`<`your_class`>` your_class_list);

【讨论】:

【参考方案8】:

这是我在 Kotlin 中的做法。

    使用 DI (Koin) 在活动中注入 room db。

     private val appDB: AppDB by inject()
    

    然后你可以简单地调用 clearAllTables()

private fun clearRoomDB() 
    GlobalScope.launch 
        appDB.clearAllTables()
        preferences.put(PreferenceConstants.IS_UPLOADCATEGORIES_SAVED_TO_DB, false)
        preferences.put(PreferenceConstants.IS_MEMBERHANDBOOK_SAVED_TO_DB, false)
    

【讨论】:

【参考方案9】:

这就是我们从 Fragment 执行此操作的方式。

fun Fragment.emptyDatabase() 
    viewLifecycleOwner.lifecycleScope.launchWhenCreated 
        withContext(Dispatchers.IO) 
            Database.getInstance(requireActivity()).clearAllTables()
        
    


如果您要从活动中清空数据库,请使用:

fun Activity.emptyDatabase() 
    // create a scope to access the database from a thread other than the main thread
    val scope = CoroutineScope(Dispatchers.Default)
    scope.launch 
        SitukaDatabase.getInstance(this@emptyDatabase).clearAllTables()
    

也可以从主线程调用clearAllTables 方法。我还没有尝试过,但我注意到 Android Studio 无法将调用识别为挂起函数。

【讨论】:

【参考方案10】:

如果有人要删除所有表格,请刷新应用程序中的所有内容,无需任何代码跟随 Device File Explorer -&gt; data -&gt; data -&gt; com.YOUR_APP -&gt; databases 你可以删除databases文件夹中的文件

【讨论】:

完美,谢谢!【参考方案11】:

如果您使用的是Rx,您可以这样做。

@Query("DELETE FROM yourDB")
void delete(); : Completable 

【讨论】:

【参考方案12】:

关于你的数据库实例调用

clearAllTables()

【讨论】:

你的回答和几年前回答的***.com/a/49545016/4744263有什么区别?

以上是关于房间持久性库。删除所有的主要内容,如果未能解决你的问题,请参考以下文章

具有新线程和数据绑定问题的房间持久库

如何在房间持久性库中使用外键

Android 房间持久性库:Upsert

如何使主键作为房间持久性库的自动增量

Android 房间持久库 - TypeConverter 错误错误:无法弄清楚如何将字段保存到数据库”

房间持久性库 - 带有 List<Video> 的嵌套对象,@Embedded 不起作用。