Biblioteca de persistência do quarto. Excluir tudo


181

Como excluir todas as entradas de uma tabela específica usando a Biblioteca de persistência da sala? Preciso descartar a tabela, mas não consigo encontrar nenhuma informação sobre como fazer isso.

Somente quando o banco de dados estiver migrando ou para carregar todas as entradas e excluí-las :)


14
Na sala 1.1.0, você pode usar o clearAllTables()que "exclui todas as linhas de todas as tabelas registradas neste banco de dados como entidades ()". Incluí isso como resposta abaixo, mas estou reproduzindo aqui para obter visibilidade.
— Dick Lucas

Respostas:


445

Você pode criar um método DAO para fazer isso.

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

3
Ah, eu não tinha pensado nisso. Eu assumi que isso @Queryse limitava a coisas que retornam conjuntos de resultados (semelhante a rawQuery()). Muito legal!
— CommonsWare

1
@yigit posso solicitar que @Deletenão use nenhum parâmetro e excluir tudo da tabela? Eu estou tentando encontrar rastreador do quarto para o arquivo que ...
— Felipe Duarte

4
Cuidado! quanto à versão alpha4 da sala, essa técnica levará a uma falha na compilação do gradle
— yshahak

1
Que tal Ids? Eu fiz isso, mas os IDs de tabela continuam aumentando. Na queda real da tabela, os IDs também são eliminados para começar novamente a partir de 0.
— Ioane Sharvadze

6
@yigit Existe uma maneira de descobrir se a consulta foi executada com sucesso ou se ocorreu um erro?
— Aditya Ladwa #

107

A partir da sala, 1.1.0você pode usar clearAllTables () que:

Exclui todas as linhas de todas as tabelas registradas neste banco de dados como entidades ().


44
Cuidado: clearAllTables () é assíncrono e não há como saber quando é concluído.
— 21418 Alexey

2
@ Alex, mas poderia haver algum problema ao tentar salvar algo após o clearAllTables? Como em, ele apenas tentará inserir APÓS a limpeza? Porque eu estou bem com isso.
— FirstOne 31/08/18

2
@FirstOne clearAllTables basicamente apenas inicia uma transação em um novo thread em segundo plano. Exclui todos os dados das tabelas e confirma essa transação. Se você iniciar sua transação depois que o clearAllTables iniciar, você estará bem. Dito isto, se você tentar inserir alguns dados logo após chamar clearAllTable, sua inserção poderá começar antes que clearAllTable inicie a transação e você perderá todos os seus dados. Se você precisar inserir novos dados logo após chamar clearAllTable, adicione pelo menos algum atraso.
— 314 Alexey

2
@Alexey Existe alguma maneira de usar um método de retorno de chamada ou semelhante para determinar o estado da transação de exclusão? Em outras palavras, se o estado da transação de exclusão estiver completo, continue com o método de inserção de dados.
— AJW

1
@AJW Não, a partir de agora, ainda não há como saber quando a operação está concluída. Se você realmente precisar dessa funcionalidade, poderá tentar algo parecido SELECT name FROM sqlite_master WHERE type='table'e, em seguida, manualmente DELETE FROM {TABLE}. Ainda não testei isso.
— 27419 Alexey

33

Se quiser excluir uma entrada da tabela na sala, basta chamar esta função,

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

Atualização: e se você deseja excluir a tabela completa, chame a função abaixo,

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

Nota: Aqui MyModel é um nome de tabela.


Eu recebi este erro após usar o erro de código de atualização: Um método abstrato do DAO deve ser anotado com uma e apenas uma das seguintes anotações: Inserir, Excluir, Consultar, Atualizar, RawQuery void delete ();
— bramastaVic

12

Use clearAllTables () com RXJava, como abaixo, 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

Eu tive problemas com excluir todos os métodos ao usar o RxJava para executar esta tarefa em segundo plano. Foi assim que finalmente resolvi:

@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 você estiver usando o Kotlin, você pode envolvê-lo em thread {}vez de futzing com o RxJava
— Erik

1

Combinando o que Dick Lucas diz e adicionando uma redefinição automática de outras postagens StackOverFlow, acho que isso pode 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()
        }
    }

Pelo que vale, achei mais fácil fazer isso via context.deleteDatabase ("name") e, em seguida, simplesmente restabelecer e repovoar o banco de dados por meio do Room.databaseBuilder (). AddCallback após o primeiro acesso.
— Bink

O que é sqlite_sequence?
— RoyalGriffin 15/04

0

Para usar a Sala sem abusar da @Queryanotação, primeiro use @Querypara selecionar todas as linhas e colocá-las em uma lista, por exemplo:

@Query("SELECT * FROM your_class_table")

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

Coloque sua lista na anotação de exclusão, por exemplo:

@Delete

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

0

Aqui está como eu fiz isso em Kotlin.

  1. Injete o banco de dados db na atividade usando DI (Koin).

     private val appDB: AppDB by inject()
  2. Então você pode simplesmente chamar clearAllTables ()

    diversão privada clearRoomDB () {GlobalScope.launch {appDB.clearAllTables () Preferences.put (PreferenceConstants.IS_UPLOADCATEGORIES_SAVED_TO_DB, false) Preferences.put (PreferenceConstants.IS_MEMBERHANDBOOK_SAVED_TO_DB, false)}}

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.