룸 지속성 라이브러리. 모두 삭제


181

Room Persistence Library를 사용하여 특정 테이블의 모든 항목을 어떻게 삭제합니까? 테이블을 삭제해야하지만이 작업을 수행하는 방법에 대한 정보를 찾을 수 없습니다.

데이터베이스가 마이그레이션 중이거나 모든 항목을로드하고 삭제하는 경우에만 해당됩니다. :)


14
1.1.0 clearAllTables()부터는 "이 데이터베이스에 엔티티 ()로 등록 된 모든 테이블에서 모든 행을 삭제합니다."를 사용할 수 있습니다 . 나는 이것을 아래 답변으로 포함했지만 가시성을 위해 여기에서 재현하고 있습니다.
Dick Lucas

답변:


445

이를 위해 DAO 방법을 만들 수 있습니다.

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

3
아, 나는 그것을 생각하지 않았다. @Query결과 집합을 반환하는 것 (akin to rawQuery()) 으로 제한 되었다고 가정했습니다 . 아주 멋지다!
CommonsWare

1
@yigit @Delete매개 변수를 사용하지 않고 테이블에서 모두 삭제 하도록 요청할 수 있습니까? 방의 추적기를 찾으려고 노력하고 있습니다 ...
Felipe Duarte

4
조심해! 방 alpha4 버전의 경우이 기술은 gradle 빌드 실패로 이어집니다 : issuetracker.google.com/issues/63608092
yshahak

1
어때요 Ids? 나는 이것을 좋아했지만 테이블 ID는 계속 증가합니다. 실제 테이블 삭제에서 ID도 0에서 다시 시작되도록 삭제됩니다.
Ioane Sharvadze

6
@yigit 쿼리가 성공적으로 실행되었는지 또는 오류가 있는지 확인하는 방법이 있습니까?
Aditya Ladwa

107

Room 기준으로 clearAllTables ()1.1.0사용할 수 있습니다 .

이 데이터베이스에 entity ()로 등록 된 모든 테이블에서 모든 행을 삭제합니다.


44
clearAllTables ()는 비동기 적이며 완료 시점을 알 수있는 방법이 없습니다.
Alexey

2
@Alexey 그러나 clearAllTables 이후에 무언가를 저장하는 데 문제가 있습니까? 에서와 같이 삭제 후에 만 ​​삽입을 시도합니까? 내가 괜찮 으니까
FirstOne

2
@FirstOne clearAllTables는 기본적으로 새로운 백그라운드 스레드에서 트랜잭션을 시작합니다. 테이블에서 모든 데이터를 삭제 한 다음 해당 트랜잭션을 커밋합니다. clearAllTables가 시작된 것보다 늦게 트랜잭션을 시작하면 괜찮습니다. 즉, clearAllTable을 호출 한 직후에 일부 데이터를 삽입하려고하면 clearAllTable이 트랜잭션을 시작하기 전에 삽입이 시작될 수 있으며 모든 데이터가 손실됩니다. clearAllTable을 호출 한 직후 새 데이터를 삽입해야하는 경우 최소한 약간의 지연을 추가하십시오.
Alexey

2
@Alexey 삭제 트랜잭션의 상태를 결정하기 위해 콜백 메소드를 사용하는 방법이 있습니까? 즉, 트랜잭션 삭제 상태가 완료되면 데이터 삽입 방법으로 진행하십시오.
AJW

1
@AJW 아니요, 현재로서는 언제 작업이 완료되었는지 알 수있는 방법이 없습니다. 이 기능이 정말로 필요한 경우에는 SELECT name FROM sqlite_master WHERE type='table'수동으로 시도해 볼 수 있습니다 DELETE FROM {TABLE}. 그래도 이것을 테스트하지 않았습니다.
Alexey

33

Room의 테이블에서 항목을 삭제하려면 간단히이 함수를 호출하십시오.

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

업데이트 : 전체 테이블을 삭제하려면 아래 함수를 호출하십시오.

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

참고 : 여기서 MyModel 은 테이블 이름입니다.


업데이트 코드 오류를 사용한 후이 오류가 발생했습니다. 다음 주석 중 하나만 사용하여 추상 DAO 메서드에 주석을 달아야합니다. Insert, Delete, Query, Update, RawQuery void delete ();
bramastaVic

12

아래의 RXJava와 함께 clearAllTables () 를 사용 하여 피하십시오.java.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

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

5
Kotlin을 사용 thread {}하는 경우 RxJava 를 사용하지 않고 랩핑 할 수 있습니다
Erik

1

Dick Lucas의 말을 결합하고 다른 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()
        }
    }

가치있는 것을 위해, 나는 context.deleteDatabase (“name”)를 통해 이것을하는 것이 가장 쉬운 것을 알았다. 그리고 처음 접근 할 때 Room.databaseBuilder (). addCallback을 통해 데이터베이스를 다시 인스턴스화하고 다시 채운다.
Bink

sqlite_sequence는 무엇입니까?
RoyalGriffin

0

@Query주석 을 남용하지 않고 Room을 사용하려면 먼저 @Query모든 행을 선택하고 목록에 넣습니다.

@Query("SELECT * FROM your_class_table")

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

그의 목록을 삭제 주석에 넣으십시오. 예를 들면 다음과 같습니다.

@Delete

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

0

다음은 Kotlin에서 수행 한 방법입니다.

  1. DI (코인)를 사용하여 활동에 방 db를 주입하십시오.

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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.