Libreria di persistenza della stanza. Cancella tutto


181

Come posso eliminare tutte le voci su una tabella specifica usando la Libreria di persistenza sala? Devo abbandonare la tabella, ma non riesco a trovare alcuna informazione su come farlo.

Solo durante la migrazione del database o per caricare tutte le voci ed eliminarle :)


14
A partire da Room 1.1.0 è possibile utilizzare clearAllTables()quale "elimina tutte le righe da tutte le tabelle registrate in questo database come entità ()." Ho incluso questo come una risposta di seguito, ma sto riproducendo qui per la visibilità.
Dick Lucas,

Risposte:


445

È possibile creare un metodo DAO per farlo.

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

3
Ah, non ci avevo pensato. Supponevo che @Queryfosse limitato a cose che restituivano insiemi di risultati (affini a rawQuery()). Molto bello!
CommonsWare,

1
@yigit posso richiedere che @Deletenon accetta alcun parametro ed eliminare tutto dalla tabella? Sto cercando di trovare il tracker di Room per archiviare questo ...
Felipe Duarte il

4
Attento! come per la versione room alpha4, questa tecnica porterà a un fallimento della compilazione graduale
yshahak,

2
Che ne dici Ids? Mi è piaciuto, ma gli ID tabella continuano ad aumentare. Nella tabella reale drop anche gli id ​​vengono rilasciati per ricominciare da 0.
Ioane Sharvadze,

6
@yigit C'è un modo per scoprire se la query è stata eseguita correttamente o se si è verificato un errore?
Aditya Ladwa,

107

A partire da Room 1.1.0puoi usare clearAllTables () che:

Elimina tutte le righe da tutte le tabelle registrate in questo database come entità ().


44
Fai attenzione: clearAllTables () è asincrono e non c'è modo di dire quando viene completato.
Alexey,

2
@Alexey ma potrebbero esserci problemi nel tentativo di salvare qualcosa dopo clearAllTables? Come in, tenterà solo di inserire DOPO la cancellazione? Perché sto bene con quello.
Primo

2
@FirstOne clearAllTables fondamentalmente avvia una transazione su un nuovo thread in background. Elimina tutti i dati dalle tabelle e quindi esegue il commit di quella transazione. Se inizi la transazione più tardi di quando clearAllTables inizia la sua, stai bene. Detto questo, se provi a inserire alcuni dati subito dopo aver chiamato clearAllTable, l'inserimento potrebbe iniziare prima che clearAllTable inizi la transazione e perderai tutti i tuoi dati. Se è necessario inserire nuovi dati subito dopo aver chiamato clearAllTable, almeno aggiungere qualche ritardo.
Alexey,

2
@Alexey Esiste un modo per utilizzare un metodo di callback o simile per determinare lo stato della transazione di eliminazione? In altre parole, se lo stato della transazione di eliminazione è completo, procedere con il metodo Inserisci dati.
AJW,

1
@AJW No, per ora non c'è ancora modo di sapere quando l'operazione è completa. Se hai davvero bisogno di questa funzionalità, potresti provare qualcosa di simile SELECT name FROM sqlite_master WHERE type='table'e poi manualmente DELETE FROM {TABLE}. Non ho provato questo però.
Alexey,

33

Se desideri eliminare una voce dalla tabella in Room, chiama semplicemente questa funzione,

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

Aggiornamento: e se desideri eliminare la tabella completa, chiama la funzione di seguito,

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

Nota: qui MyModel è un nome tabella.


ho ricevuto questo errore dopo l'uso dell'errore del codice di aggiornamento: un metodo DAO astratto deve essere annotato con una e solo una delle seguenti annotazioni: Inserisci, Elimina, Query, Aggiorna, RawQuery void delete ();
bramastaVic

12

Utilizzare clearAllTables () con RXJava come inorder in basso per evitarejava.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

Ho avuto problemi con l'eliminazione di tutti i metodi durante l'utilizzo di RxJava per eseguire questa attività in background. Ecco come l'ho finalmente risolto:

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

e

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

5
Quando stai usando Kotlin, puoi semplicemente avvolgerlo thread {}invece di perdere tempo con RxJava
Erik

1

Combinando ciò che dice Dick Lucas e aggiungendo un reset automatico dagli altri post StackOverFlow, penso che possa funzionare:

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

Per quello che vale, ho trovato più semplice farlo tramite context.deleteDatabase ("nome") e quindi semplicemente reintegrare e ripopolare il database tramite Room.databaseBuilder (). AddCallback al primo accesso.
Bink,

Che cos'è sqlite_sequence?
RoyalGriffin,

0

Per utilizzare la Stanza senza abuso @Querydell'annotazione, utilizzare innanzitutto @Queryper selezionare tutte le righe e inserirle in un elenco, ad esempio:

@Query("SELECT * FROM your_class_table")

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

Inserisci il suo elenco nell'annotazione di eliminazione, ad esempio:

@Delete

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

0

Ecco come l'ho fatto a Kotlin.

  1. Iniettare la stanza db nell'attività usando DI (Koin).

     private val appDB: AppDB by inject()
  2. Quindi puoi semplicemente chiamare clearAllTables ()

    divertimento privato clearRoomDB () {GlobalScope.launch {appDB.clearAllTables () preferenze.put (PreferenceConstants.IS_UPLOADCATEGORIES_SAVED_TO_DB, false) preferenze.put (PreferenceConstants.IS_MEMBERHANDBOOK_SAVED_TO_DB, false)}

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.