Phòng thư viện kiên trì. Xóa hết


181

Làm cách nào tôi có thể xóa tất cả các mục trên bảng cụ thể bằng Thư viện liên tục trong phòng? Tôi cần phải bỏ bảng, nhưng tôi không thể tìm thấy bất kỳ thông tin nào để làm điều này.

Chỉ khi cơ sở dữ liệu đang di chuyển hoặc tải tất cả các mục và xóa chúng :)


14
Kể từ Phòng 1.1.0, bạn có thể sử dụng clearAllTables()"xóa tất cả các hàng khỏi tất cả các bảng được đăng ký vào cơ sở dữ liệu này dưới dạng thực thể ()." Tôi đã bao gồm điều này như một câu trả lời dưới đây, nhưng đang tái tạo ở đây để nhìn thấy.
Dick Lucas

Câu trả lời:


445

Bạn có thể tạo một phương thức DAO để làm điều này.

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

3
Ah, tôi đã không nghĩ về điều đó. Tôi giả định rằng nó @Querybị giới hạn ở những thứ trả về tập kết quả (gần giống rawQuery()). Rất tuyệt!
CommonsWare

1
@yigit tôi có thể yêu cầu @Deletekhông có tham số và xóa tất cả khỏi bảng không? Tôi đang cố gắng tìm trình theo dõi của Room để gửi ...
Felipe Duarte

4
Coi chừng! đối với phiên bản alpha4 phòng, kỹ thuật này sẽ dẫn đến việc xây dựng lớp không thành công: suetracker.google.com/issues/63608092
yshahak

1
Thế còn Ids? Tôi đã làm như vậy nhưng Id bảng tiếp tục tăng. Trong bảng thực tế, Id cũng được thả để bắt đầu lại từ 0.
Ioane Sharvadze

6
@yigit Có cách nào để tìm hiểu xem truy vấn đã chạy thành công hay có lỗi không?
Aditya Ladwa

107

Kể từ Room, 1.1.0bạn có thể sử dụng ClearAllTables () trong đó:

Xóa tất cả các hàng khỏi tất cả các bảng được đăng ký vào cơ sở dữ liệu này dưới dạng các thực thể ().


44
Hãy cẩn thận: clearAllTables () không đồng bộ và không có cách nào để biết khi nào nó hoàn thành.
Alexey

2
@Alexey nhưng có thể có bất kỳ rắc rối nào khi cố gắng lưu thứ gì đó sau ClearAllTables không? Như trong, nó sẽ chỉ cố gắng chèn SAU? Bởi vì tôi ổn với điều đó.
Đầu tiên vào

2
@FirstOne clearAllTables về cơ bản chỉ bắt đầu một giao dịch trên một luồng nền mới. Nó xóa tất cả dữ liệu khỏi các bảng và sau đó thực hiện giao dịch đó. Nếu bạn bắt đầu giao dịch của mình muộn hơn ClearAllTables bắt đầu giao dịch, bạn vẫn ổn. Điều đó đang được nói, nếu bạn cố gắng chèn một số dữ liệu ngay sau khi gọi ClearAllTable, phần chèn của bạn có thể bắt đầu trước khi ClearAllTable bắt đầu giao dịch và bạn sẽ mất tất cả dữ liệu của mình. Nếu bạn cần chèn dữ liệu mới ngay sau khi gọi ClearAllTable, ít nhất hãy thêm một số độ trễ.
Alexey

2
@Alexey Có cách nào để sử dụng phương thức gọi lại hoặc tương tự để xác định trạng thái của giao dịch xóa không? Nói cách khác, nếu trạng thái giao dịch xóa hoàn tất, thì hãy tiến hành phương thức chèn dữ liệu.
AJW

1
@AJW Không, cho đến bây giờ, vẫn không có cách nào để biết khi nào hoạt động hoàn tất. Nếu bạn thực sự cần chức năng này, bạn có thể muốn thử một cái gì đó như thế SELECT name FROM sqlite_master WHERE type='table'và sau đó bằng tay DELETE FROM {TABLE}. Không thử nghiệm điều này mặc dù.
Alexey

33

Nếu muốn xóa một mục từ bảng trong Phòng, chỉ cần gọi chức năng này,

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

Cập nhật: Và nếu bạn muốn xóa bảng hoàn chỉnh, hãy gọi hàm dưới đây,

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

Lưu ý: Ở đây MyModel là Tên bảng.


Tôi đã gặp lỗi này sau khi sử dụng lỗi mã cập nhật của bạn: Một phương pháp DAO trừu tượng phải được chú thích bằng một và chỉ một trong các chú thích sau: Chèn, Xóa, Truy vấn, Cập nhật, RawQuery void remove ();
bramastaVic

12

Sử dụng ClearAllTables () với RXJava như bên dưới inorder để tránhjava.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

Tôi gặp vấn đề với việc xóa tất cả phương thức khi sử dụng RxJava để thực thi tác vụ này trên nền. Đây là cách cuối cùng tôi đã giải quyết nó:

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

5
Khi bạn đang sử dụng Kotlin, bạn có thể chỉ cần bọc nó thread {}thay vì đóng gói với RxJava
Erik

1

Kết hợp những gì Dick Lucas nói và thêm tự động thiết lập lại từ các bài đăng StackOverFlow khác, tôi nghĩ rằng điều này có thể hoạt động:

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

Để biết giá trị của nó, tôi đã thấy dễ dàng nhất để thực hiện việc này thông qua bối cảnh.deleteDatabase (tên của tên) và sau đó chỉ cần khôi phục và khôi phục cơ sở dữ liệu thông qua Room.databaseBuilder (). AddCallback khi truy cập lần đầu.
Bink

Sqlite_ Hậu quả là gì?
RoyalGriffin

0

Để sử dụng Phòng mà không lạm dụng @Querychú thích, trước tiên, sử dụng @Queryđể chọn tất cả các hàng và đưa chúng vào danh sách, ví dụ:

@Query("SELECT * FROM your_class_table")

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

Đặt danh sách của anh ấy vào chú thích xóa, ví dụ:

@Delete

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

0

Đây là cách tôi đã thực hiện nó trong Kotlin.

  1. Tiêm db phòng trong hoạt động bằng DI (Koin).

     private val appDB: AppDB by inject()
  2. Sau đó, bạn có thể chỉ cần gọi ClearAllTables ()

    riêng tư vui vẻ ClearRoomDB () {GlobalScope.launch {appDB.clear ALLTables () Preferences.put (PreferenceConstants.IS_UPLOADCATEGORIES_SAVED_TO_DB, false) Preferences.put (PreferenceConstants.IS_MEMBERHAND

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.