部屋の永続化ライブラリ。すべて削除


181

Room Persistence Libraryを使用して特定のテーブルのすべてのエントリを削除するにはどうすればよいですか?テーブルを削除する必要がありますが、これを行う方法に関する情報が見つかりません。

データベースが移行中の場合、またはすべてのエントリをロードして削除する場合のみ:)


14
Room 1.1.0 clearAllTables()以降では、「entities()としてこのデータベースに登録されているすべてのテーブルからすべての行を削除する」を使用できます。これを以下の回答として含めましたが、見やすくするためにここで再現しています。
ディックルーカス

回答:


445

これを行うためのDAOメソッドを作成できます。

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

3
ああ、そんなことは考えていなかった。私はそれ@Queryが結果セットを返すものに限定されていると思いました(に似ていますrawQuery())。とてもかっこいい!
CommonsWare 2017年

1
@yigit @Deleteは、パラメーターを使用せずにテーブルからすべて削除するように要求できますか?私はそれを提出するために部屋のトラッカーを見つけようとしています...
フェリペ・ドゥアルテ

4
気を付けて!部屋のalpha4バージョンと同様に、この手法はGradle
yshahak

1
いかがIdsですか?私はこれが好きでしたが、テーブルIDは増え続けています。実際のテーブルドロップでは、IDもドロップされ、0から再び開始されます。
Ioane Sharvadze 2017

6
@yigitクエリが正常に実行されたかどうか、またはエラーが発生したかどうかを確認する方法はありますか?
Aditya Ladwa 2017

107

Room以降1.1.0では、clearAllTables()を使用して次のことができます。

このデータベースにentity()として登録されているすべてのテーブルからすべての行を削除します。


44
注意:clearAllTables()は非同期であり、完了したことを通知する方法はありません。
Alexey

2
@Alexeyですが、clearAllTablesの後で何かを保存しようとして問題が発生する可能性はありますか?のように、それはクリア後の挿入のみを試みますか?それで大丈夫だから。
FirstOne 2018

2
@FirstOne clearAllTablesは、基本的に新しいバックグラウンドスレッドでトランザクションを開始するだけです。テーブルからすべてのデータを削除し、そのトランザクションをコミットします。clearAllTablesがトランザクションを開始するよりも後にトランザクションを開始する場合は、問題ありません。つまり、clearAllTableを呼び出した直後にデータを挿入しようとすると、clearAllTableがトランザクションを開始する前に挿入が開始される可能性があり、すべてのデータが失われます。clearAllTableを呼び出した直後に新しいデータを挿入する必要がある場合は、少なくとも遅延を追加してください。
Alexey

2
@Alexeyコールバックメソッドなどを使用して削除トランザクションの状態を判断する方法はありますか?つまり、トランザクションの削除状態が完了した場合は、データの挿入メソッドに進みます。
AJW 2019

1
@AJWいいえ、現在のところ、操作がいつ完了したかを知る方法はまだありません。この機能が本当に必要な場合は、次のようなことを試してSELECT name FROM sqlite_master WHERE type='table'から手動で試してくださいDELETE FROM {TABLE}。これはまだテストしていません。
Alexey

33

ルームのテーブルからエントリを削除する場合は、この関数を呼び出すだけです。

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

更新:テーブル全体を削除したい場合は、以下の関数を呼び出してください。

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

注:ここでMyModelはテーブル名です。


更新コードエラーの使用後にこのエラーが発生しました:抽象DAOメソッドには、次のアノテーションの1つだけでアノテーションを付ける必要があります:Insert、Delete、Query、Update、RawQuery void delete();
bramastaVic

12

回避するために、以下のようなRXJavaでclearAllTables()を使用します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());


                }
            });

4

RxJavaを使用してこのタスクをバックグラウンドで実行すると、delete allメソッドで問題が発生しました。これは私が最終的にそれを解決した方法です:

@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を使用してデータベースを再インスタンス化して再設定するのが最も簡単なことです。
2018年

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()を呼び出すだけです。

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.