Sala de persistencia biblioteca. Eliminar todos


181

¿Cómo puedo eliminar todas las entradas en una tabla específica usando la Biblioteca de persistencia de sala? Necesito abandonar la tabla, pero no puedo encontrar ninguna información sobre cómo hacerlo.

Solo cuando la base de datos está migrando o para cargar todas las entradas y eliminarlas :)


14
A partir de la habitación 1.1.0, puede usar el clearAllTables()que "elimina todas las filas de todas las tablas que están registradas en esta base de datos como entidades ()". He incluido esto como respuesta a continuación, pero estoy reproduciendo aquí para mayor visibilidad.
Dick Lucas

Respuestas:


445

Puede crear un método DAO para hacer esto.

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

3
Ah, no había pensado en eso. Supuse que @Queryse limitaba a cosas que devuelven conjuntos de resultados (similares a rawQuery()). ¡Muy genial!
CommonsWare

1
@yigit, ¿puedo solicitar que @Deleteno tome ningún parámetro y eliminar todo de la tabla? Estoy tratando de encontrar el rastreador de Room para archivar eso ...
Felipe Duarte

44
¡Cuidado! En cuanto a la versión de la sala alpha4, esta técnica provocará un error de construcción de gradle
yshahak

2
¿Qué tal Ids? Me gustó esto, pero los ID de tabla continúan incrementándose. En la caída de la tabla real, los ID también se descartan para comenzar desde 0 nuevamente.
Ioane Sharvadze

66
@yigit ¿Hay alguna forma de averiguar si la consulta se ejecutó correctamente o si hubo un error?
Aditya Ladwa

107

A partir de Room 1.1.0, puede usar clearAllTables () que:

Elimina todas las filas de todas las tablas que están registradas en esta base de datos como entidades ().


44
Tenga cuidado: clearAllTables () es asíncrono y no hay forma de saber cuándo se completa.
Alexey

2
@Alexey, pero ¿podría haber algún problema al intentar guardar algo después de clearAllTables? Como en, ¿solo intentará insertar DESPUÉS de la limpieza? Porque estoy bien con eso.
FirstOne

2
@FirstOne clearAllTables básicamente solo inicia una transacción en un nuevo hilo de fondo. Elimina todos los datos de las tablas y luego confirma esa transacción. Si comienza su transacción más tarde de lo que clearAllTables comienza, está bien. Dicho esto, si intenta insertar algunos datos justo después de llamar a clearAllTable, su inserción podría comenzar antes de que clearAllTable comience la transacción y perderá todos sus datos. Si necesita insertar datos nuevos justo después de llamar a clearAllTable, al menos agregue algún retraso.
Alexey

2
@Alexey ¿Hay alguna forma de usar un método de devolución de llamada o similar para determinar el estado de la transacción de eliminación? En otras palabras, si el estado de la transacción de eliminación está completo, continúe con el método de inserción de datos.
AJW

1
@AJW No, a partir de ahora, todavía no hay forma de saber cuándo se completó la operación. Si realmente necesita esta funcionalidad, es posible que desee probar algo como SELECT name FROM sqlite_master WHERE type='table'y luego manualmente DELETE FROM {TABLE}. Sin embargo, no he probado esto.
Alexey

33

Si desea eliminar una entrada de la tabla en la sala, simplemente llame a esta función,

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

Actualización: y si desea eliminar la tabla completa, llame a la siguiente función,

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

Nota: Aquí MyModel es un nombre de tabla.


recibí este error después de usar su error de código de actualización: un método DAO abstracto debe ser anotado con una y solo una de las siguientes anotaciones: Insertar, Eliminar, Consultar, Actualizar, RawQuery void delete ();
bramastaVic

12

Use clearAllTables () con RXJava como se muestra a continuación para evitarjava.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

Tuve problemas con eliminar todo el método al usar RxJava para ejecutar esta tarea en segundo plano. Así es como finalmente lo resolví:

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

y

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

55
Cuando usa Kotlin, puede envolverlo en thread {}lugar de usarlo en el futx con RxJava
Erik

1

Combinando lo que dice Dick Lucas y agregando un reinicio automático de otras publicaciones de StackOverFlow, creo que esto puede funcionar:

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

Para lo que vale, he encontrado que es más fácil hacer esto a través de context.deleteDatabase ("nombre") y luego simplemente reinstalar y repoblar la base de datos a través de Room.databaseBuilder (). AddCallback al primer acceso.
Bink

¿Qué es sqlite_sequence?
RoyalGriffin

0

Para utilizar la sala sin abusar de la @Queryanotación, primero use @Querypara seleccionar todas las filas y ponerlas en una lista, por ejemplo:

@Query("SELECT * FROM your_class_table")

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

Ponga su lista en la anotación de eliminación, por ejemplo:

@Delete

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

0

Así es como lo hice en Kotlin.

  1. Inyecte la habitación db en la actividad usando DI (Koin).

     private val appDB: AppDB by inject()
  2. Entonces simplemente puede llamar a clearAllTables ()

    private fun clearRoomDB () {GlobalScope.launch {appDB.clearAllTables () preferencias.put (PreferenceConstants.IS_UPLOADCATEGORIES_SAVED_TO_DB, false) preferencias.put (PreferenceConstants.IS_MEMBERHANDBOOK_SAVED_TO_DB, false)}}

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.