房间持久性库。删除所有


181

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

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


14
从1.1.0版开始,您可以使用clearAllTables()“从作为entry()注册到此数据库的所有表中删除所有行”。我已经在下面将其作为答案,但此处出于可见性而复制。
迪克·卢卡斯

Answers:


442

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

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

3
啊,我没想到。我以为那只@Query限于返回结果集的内容(类似于rawQuery())。很酷!
CommonsWare

1
我可以要求@yigit @Delete不带参数并从表中删除所有参数吗?我正在尝试查找Room的跟踪器来归档该文件…
Felipe Duarte

4
小心!至于房间alpha4版本,此技术将导致gradle构建失败:issuetracker.google.com/issues/63608092
yshahak

1
怎么Ids样 我确实喜欢这样,但是表ID继续增加。在实际表删除中,Id也会再次从0开始删除。
艾奥恩·沙尔瓦兹

6
@yigit是否可以找出查询是否成功运行或是否有错误?
Aditya Ladwa

106

从Room开始,1.1.0您可以使用clearAllTables()

从所有以entities()形式注册到此数据库的表中删除所有行。


44
注意:clearAllTables()是异步的,没有办法告诉它何时完成。
Alexey '18

2
@Alexey,但是在clearAllTables之后尝试保存内容是否会有任何麻烦?与之类似,它将仅尝试插入AFTER清除后?因为我很好。
FirstOne

2
@FirstOne clearAllTables基本上只是在新的后台线程上启动事务。它从表中删除所有数据,然后提交该事务。如果您在clearAllTables启动之前启动事务,则可以。话虽如此,如果您尝试在调用clearAllTable之后立即插入一些数据,则插入可能会在clearAllTable开始事务之前开始,并且您将丢失所有数据。如果您需要在调用clearAllTable之后立即插入新数据,请至少添加一些延迟。
阿列克谢

2
@Alexey是否可以使用回调方法或类似方法确定删除事务的状态?换句话说,如果删除事务状态已完成,则继续执行插入数据方法。
AJW

1
@AJW不,到目前为止,仍然没有办法告诉操作何时完成。如果您确实需要此功能,则可能需要尝试类似的方法SELECT name FROM sqlite_master WHERE type='table',然后手动进行DELETE FROM {TABLE}。尚未测试过。
阿列克谢

33

如果要从“房间”表中删除条目,只需调用此函数,

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

更新:如果您要删除完整表格,请调用以下函数,

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

注:这里为MyModel是一个表名。


使用更新代码错误后出现此错误:抽象DAO方法必须使用以下注释之一进行注释,并且只能使用以下注释之一:Insert,Delete,Query,Update,RawQuery void delete();
bramastaVic

12

像下面这样将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());


                }
            });

3

使用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)
}

5
使用Kotlin时,您可以将其包装起来,thread {}而不必使用RxJava进行融合
Erik

1

结合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重新实例化并重新填充数据库。
宾克(Bink),

什么是sqlite_sequence?
RoyalGriffin

0

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

@Query("SELECT * FROM your_class_table")

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

将其列表放入删除批注中,例如:

@Delete

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

0

这就是我在科特林所做的工作。

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

     private val appDB: AppDB by inject()
  2. 然后,您可以简单地调用clearAllTables()

    私人乐趣clearRoomDB(){GlobalScope.launch {appDB.clearAllTables()preferences.put(PreferenceConstants.IS_UPLOADCATEGORIES_SAVED_TO_DB,false)preferences.put(PreferenceConstants.IS_MEMBERHANDBOOK_SAVED_TO_DB,false)}}

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.