Raumbeständigkeitsbibliothek. Alles löschen


181

Wie kann ich alle Einträge in einer bestimmten Tabelle mithilfe der Room Persistence Library löschen? Ich muss die Tabelle löschen, kann aber keine Informationen dazu finden.

Nur wenn die Datenbank migriert oder alle Einträge geladen und gelöscht werden :)


14
Ab Raum 1.1.0 können Sie Folgendes verwenden: clearAllTables()"Löscht alle Zeilen aus allen Tabellen, die in dieser Datenbank als Entitäten registriert sind ()." Ich habe dies als Antwort unten angegeben, reproduziere es hier jedoch zur besseren Sichtbarkeit.
Dick Lucas

Antworten:


442

Sie können dazu eine DAO-Methode erstellen.

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

3
Ah, daran hatte ich nicht gedacht. Ich nahm an, dass dies @Queryauf Dinge beschränkt war, die Ergebnismengen zurückgeben (ähnlich rawQuery()). Sehr cool!
CommonsWare

1
@yigit kann ich anfordern, dass @Deletekein Parameter verwendet wird und alle aus der Tabelle löschen? Ich versuche, Room's Tracker zu finden, um das einzureichen ...
Felipe Duarte

4
Achtung! In der Raum-Alpha4-Version führt diese Technik zu einem fehlgeschlagenen Gradle-Build: issuetracker.google.com/issues/63608092
yshahak

1
Wie wäre es Ids? Das hat mir gefallen, aber die Tabellen-IDs werden weiter erhöht. In realen Tabellen werden Drop-IDs ebenfalls gelöscht, um wieder bei 0 zu beginnen.
Ioane Sharvadze

6
@yigit Gibt es eine Möglichkeit herauszufinden, ob die Abfrage erfolgreich ausgeführt wurde oder ob ein Fehler aufgetreten ist?
Aditya Ladwa

105

Ab Room können 1.1.0Sie clearAllTables () verwenden, die:

Löscht alle Zeilen aus allen Tabellen, die als Entitäten () in dieser Datenbank registriert sind.


44
Seien Sie vorsichtig: clearAllTables () ist asynchron und es gibt keine Möglichkeit zu erkennen, wann es abgeschlossen ist.
Alexey

2
@Alexey, aber könnte es Probleme geben, nach clearAllTables etwas zu speichern? Wird wie in nur versucht, nach dem Löschen einzufügen? Weil ich damit einverstanden bin.
FirstOne

2
@FirstOne clearAllTables startet im Grunde nur eine Transaktion in einem neuen Hintergrundthread. Es löscht alle Daten aus Tabellen und schreibt diese Transaktion fest. Wenn Sie Ihre Transaktion später als clearAllTables starten, ist alles in Ordnung. Wenn Sie jedoch versuchen, einige Daten direkt nach dem Aufruf von clearAllTable einzufügen, wird Ihre Einfügung möglicherweise gestartet, bevor clearAllTable die Transaktion startet, und Sie verlieren alle Ihre Daten. Wenn Sie direkt nach dem Aufruf von clearAllTable neue Daten einfügen müssen, fügen Sie mindestens eine Verzögerung hinzu.
Alexey

2
@Alexey Gibt es eine Möglichkeit, eine Rückrufmethode oder ähnliches zu verwenden, um den Status der Löschtransaktion zu bestimmen? Mit anderen Worten, wenn der Löschtransaktionsstatus abgeschlossen ist, fahren Sie mit der Methode zum Einfügen von Daten fort.
AJW

1
@AJW Nein, derzeit kann noch nicht festgestellt werden, wann der Vorgang abgeschlossen ist. Wenn Sie diese Funktionalität wirklich benötigen, können Sie etwas wie SELECT name FROM sqlite_master WHERE type='table'und dann manuell ausprobieren DELETE FROM {TABLE}. Habe das aber nicht getestet.
Alexey

33

Wenn Sie einen Eintrag aus der Tabelle in Room löschen möchten, rufen Sie einfach diese Funktion auf.

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

Update: Und wenn Sie die vollständige Tabelle löschen möchten, rufen Sie die folgende Funktion auf:

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

Hinweis: Hier ist MyModel ein Tabellenname.


Ich habe diesen Fehler erhalten, nachdem ich Ihren Update-Code-Fehler verwendet habe: Eine abstrakte DAO-Methode muss mit einer und nur einer der folgenden Annotationen versehen werden: Einfügen, Löschen, Abfragen, Aktualisieren, RawQuery void delete ();
BramastaVic

12

Verwenden Sie clearAllTables () mit RXJava wie unten beschrieben, um dies zu vermeidenjava.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

Ich hatte Probleme beim Löschen aller Methoden, wenn ich RxJava zum Ausführen dieser Aufgabe im Hintergrund verwendete. So habe ich es endlich gelöst:

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

und

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

5
Wenn Sie Kotlin verwenden, können Sie es einfach thread {}einpacken, anstatt mit RxJava
Erik

1

Wenn ich das kombiniere, was Dick Lucas sagt, und ein Reset automatisch inkrementell aus anderen StackOverFlow-Posts hinzufüge, denke ich, dass dies funktionieren kann:

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

Für das, was es wert ist, habe ich es am einfachsten gefunden, dies über context.deleteDatabase ("name") zu tun und dann die Datenbank beim ersten Zugriff einfach über Room.databaseBuilder () neu zu etablieren und neu zu füllen. AddCallback.
Bink

Was ist sqlite_sequence?
RoyalGriffin

0

Um den Raum ohne Missbrauch der @QueryAnmerkung zu nutzen @Query, wählen Sie zunächst alle Zeilen aus und fügen Sie sie in eine Liste ein. Beispiel:

@Query("SELECT * FROM your_class_table")

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

Fügen Sie seine Liste in die Löschanmerkung ein, zum Beispiel:

@Delete

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

0

So habe ich es in Kotlin gemacht.

  1. Injizieren Sie Raum db in die Aktivität mit DI (Koin).

     private val appDB: AppDB by inject()
  2. Dann können Sie einfach clearAllTables () aufrufen.

    privater Spaß clearRoomDB () {GlobalScope.launch {appDB.clearAllTables () settings.put (PreferenceConstants.IS_UPLOADCATEGORIES_SAVED_TO_DB, false) settings.put (PreferenceConstants.IS_MEMBERHANDBOOK_SAVED_TO_DB, false)}}

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.