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

Sirelon
quelle
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();
}
Yigit
quelle
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.

Dick Lucas
quelle
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.

Aman Gupta - SHOoTeR
quelle
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());


                }
            });
Adewale Balogun
quelle
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)
}
Micer
quelle
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()
        }
    }
Weiler Leon
quelle
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);
Dirk Fraanje
quelle
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)}}

VIVEK CHOUDHARY
quelle