Как удалить все записи в определенной таблице с помощью библиотеки Room Persistence Library? Мне нужно удалить таблицу, но я не могу найти никакой информации о том, как это сделать.

Особенно при миграции базы данных или для загрузки всех записей и их удаления :)

Ответы (12)

Для этого можно создать метод DAO.

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

Чтобы использовать Room без злоупотребления аннотацией @Query, сначала используйте @Query, чтобы выбрать все строки и поместить их в список, например:

@Query("SELECT * FROM your_class_table")

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

Поместите его список, например, в аннотацию удаления:

@Delete

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

если вы используете Rx, вы можете сделать это.

@Query("DELETE FROM yourDB")
void delete(); : Completable 

В экземпляре вашей базы данных вызовите

clearAllTables()

Если кто-то ищет, как удалить все таблицы, обновить все в приложении без какого-либо кода, следуйте
Device File Explorer -> data -> data -> com.YOUR_APP -> databases
вы можете удалить файлы внутри папки databases

Сочетая то, что говорит Дик Лукас, и добавляя автоинкремент сброса из других постов StackOverFlow, я думаю, что это может сработать:

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

Используйте clearAllTables() с RXJava, как показано ниже, чтобы избежать java.lang.IllegalStateException: Невозможно получить доступ к базе данных в основном потоке, поскольку это может потенциально заблокировать пользовательский интерфейс на длительный период времени.

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() {
                @Override
                public void accept(Throwable throwable) throws Exception {
                    Log.d(TAG, "--- clearAllTables(): accept(Throwable throwable) ----");
                    Log.d(TAG, "throwable.getMessage(): "+throwable.getMessage());


                }
            });

Вот как я сделал это в Kotlin.

  1. Введите комнату db в активность с помощью DI (Koin).

     private val appDB: AppDB by inject()
    
  2. Тогда вы можете просто вызвать clearAllTables()

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

Начиная с номера 1.1.0 вы можете использовать clearAllTables(), который:

Удаляет все строки из всех таблиц, которые зарегистрированы в этой базе данных как entities().

Если вы хотите удалить запись из таблицы в Room, просто вызовите эту функцию,

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

Обновление: А если вы хотите удалить всю таблицу, вызовите следующую функцию,

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

Примечание: Здесь MyModel - это имя таблицы.

У меня были проблемы с методом delete all при использовании RxJava для выполнения этой задачи в фоновом режиме. Вот как я наконец решил эту проблему:

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

и

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

Вот как мы делаем это из фрагмента.

fun Fragment.emptyDatabase() {
    viewLifecycleOwner.lifecycleScope.launchWhenCreated {
        withContext(Dispatchers.IO) {
            Database.getInstance(requireActivity()).clearAllTables()
        }
    }
}

Если вы очищаете базу данных от активности, используйте следующее:

fun Activity.emptyDatabase() {
    // create a scope to access the database from a thread other than the main thread
    val scope = CoroutineScope(Dispatchers.Default)
    scope.launch {
        SitukaDatabase.getInstance(this@emptyDatabase).clearAllTables()
    }
}

Также можно вызвать метод clearAllTables из главного потока. Я еще не пробовал, но заметил, что Android Studio не распознает этот вызов как функцию приостановки.

2022 WebDevInsider