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

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

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

【问题讨论】:

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

标签: android android-room android-architecture-components


【解决方案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 所说的内容并从其他 StackOverFlow 帖子中添加重置自动增量,我认为这可以工作:

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 中的做法。

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

         private val appDB: AppDB by inject()
        
      2. 然后你可以简单地调用 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()

            【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2018-05-27
            • 2018-01-22
            • 1970-01-01
            • 2018-06-08
            • 2020-03-19
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多