Perpustakaan persisten ruang. Hapus semua


181

Bagaimana saya bisa menghapus semua entri pada tabel tertentu menggunakan Perpustakaan Persistensi Kamar? Saya perlu drop table, tetapi saya tidak dapat menemukan informasi bagaimana melakukan ini.

Hanya ketika database dimigrasi atau memuat semua entri dan menghapusnya :)


14
Pada Kamar 1.1.0 Anda dapat menggunakan clearAllTables()yang "menghapus semua baris dari semua tabel yang terdaftar ke database ini sebagai entitas ()." Saya memasukkan ini sebagai jawaban di bawah, tetapi saya mereproduksi di sini untuk visibilitas.
Dick Lucas

Jawaban:


445

Anda dapat membuat metode DAO untuk melakukan ini.

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

3
Ah, saya belum memikirkan itu. Saya berasumsi bahwa @Queryitu terbatas pada hal-hal yang mengembalikan set hasil (mirip dengan rawQuery()). Sangat keren!
CommonsWare

1
@yigit, bisakah saya meminta yang @Deletetidak memiliki parameter dan menghapus semua dari tabel? Saya mencoba mencari pelacak Kamar untuk mengarsipkan itu ...
Felipe Duarte

4
Awas! Sedangkan untuk versi kamar alpha4, teknik ini akan menyebabkan kegagalan gradle build: issuetracker.google.com/issues/63608092
yshahak

1
Bagaimana dengan Ids? Saya memang suka ini tetapi Id Tabel terus bertambah. Dalam tabel drop nyata Id juga turun mulai dari 0 lagi.
Ioane Sharvadze

6
@yigit Apakah ada cara untuk mengetahui apakah kueri berjalan dengan sukses atau jika ada kesalahan?
Aditya Ladwa

107

Pada Kamar 1.1.0Anda dapat menggunakan clearAllTables () yang:

Menghapus semua baris dari semua tabel yang terdaftar ke database ini sebagai entitas ().


44
Hati-hati: clearAllTables () asynchronous dan tidak ada cara untuk mengetahui kapan itu selesai.
Alexey

2
@ Alexey tapi bisakah ada masalah mencoba menyimpan sesuatu setelah clearAllTables? Seperti pada, apakah hanya akan mencoba memasukkan SETELAH kliring? Karena aku baik-baik saja dengan itu.
FirstOne

2
@FirstOne clearAllTables pada dasarnya baru saja memulai transaksi pada utas latar belakang baru. Itu menghapus semua data dari tabel dan kemudian melakukan transaksi itu. Jika Anda memulai transaksi Anda lebih lambat dari clearAllTables memulai, Anda baik-baik saja. Yang sedang berkata, Jika Anda mencoba untuk memasukkan beberapa data tepat setelah memanggil clearAllTable insert Anda mungkin mulai sebelum clearAllTable memulai transaksi dan Anda akan kehilangan semua data Anda. Jika Anda perlu memasukkan data baru setelah menelepon clearAllTable, setidaknya tambahkan beberapa penundaan.
Alexey

2
@ Alexey Apakah ada cara untuk menggunakan metode panggilan balik atau sejenisnya untuk menentukan keadaan transaksi hapus? Dengan kata lain, jika status hapus transaksi selesai, maka lanjutkan dengan metode memasukkan data.
AJW

1
@ AJW Tidak, sampai sekarang, masih belum ada cara untuk mengetahui kapan operasi selesai. Jika Anda benar-benar membutuhkan fungsi ini, Anda mungkin ingin mencoba sesuatu seperti SELECT name FROM sqlite_master WHERE type='table'dan kemudian secara manual DELETE FROM {TABLE}. Belum diuji ini.
Alexey

33

Jika ingin menghapus entri dari tabel di Kamar cukup panggil fungsi ini,

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

Pembaruan: Dan jika Anda ingin menghapus tabel lengkap, panggil fungsi di bawah ini,

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

Catatan: Di sini MyModel adalah Nama Tabel.


saya mendapatkan kesalahan ini setelah menggunakan kesalahan kode pembaruan Anda: Metode DAO abstrak harus dijelaskan dengan satu dan hanya satu dari anotasi berikut: Sisipkan, Hapus, Kueri, Perbarui, RawQuery batal hapus ();
bramastaVic

12

Gunakan clearAllTables () dengan RXJava seperti di bawah ini untuk menghindarijava.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

Saya memiliki masalah dengan menghapus semua metode saat menggunakan RxJava untuk menjalankan tugas ini di latar belakang. Beginilah akhirnya saya menyelesaikannya:

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

dan

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

5
Saat Anda menggunakan Kotlin, Anda hanya bisa membungkusnya dan tidak thread {}menggunakan RxJava
Erik

1

Menggabungkan apa yang dikatakan Dick Lucas dan menambahkan reset autoincremental dari postingan StackOverFlow lainnya, saya pikir ini bisa bekerja:

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

Untuk apa nilainya, saya merasa paling mudah untuk melakukan ini melalui context.deleteDatabase ("name") dan kemudian cukup mengembalikan dan mengisi kembali database melalui Room.databaseBuilder (). AddCallback setelah akses pertama.
Bink

Apa itu sqlite_afterence?
RoyalGriffin

0

Untuk menggunakan Kamar tanpa penyalahgunaan @Queryanotasi, gunakan dulu @Queryuntuk memilih semua baris dan memasukkannya ke dalam daftar, misalnya:

@Query("SELECT * FROM your_class_table")

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

Masukkan daftarnya ke dalam anotasi penghapusan, misalnya:

@Delete

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

0

Inilah cara saya melakukannya di Kotlin.

  1. Suntikkan room db dalam aktivitas menggunakan DI (Koin).

     private val appDB: AppDB by inject()
  2. Maka Anda cukup memanggil clearAllTables ()

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

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.