房间持久性库。删除所有
Posted
技术标签:
【中文标题】房间持久性库。删除所有【英文标题】:Room persistance library. Delete all 【发布时间】:2017-10-29 21:09:59 【问题描述】:如何使用 Room Persistence Library 删除特定表上的所有条目? 我需要删除表,但我找不到任何信息如何执行此操作。
仅当数据库正在迁移或加载所有条目并删除它们时:)
【问题讨论】:
从 Room 1.1.0 开始,您可以使用clearAllTables()
,它“从作为实体()注册到此数据库的所有表中删除所有行”。我已将其作为答案包含在下面,但我在这里复制以提高知名度。
【参考方案1】:
您可以创建一个 DAO 方法来执行此操作。
@Dao
interface MyDao
@Query("DELETE FROM myTableName")
public void nukeTable();
【讨论】:
啊,我没想到。我假设@Query
仅限于返回结果集的东西(类似于rawQuery()
)。很酷!
@yigit 我可以要求@Delete
不带参数并从表中删除所有参数吗?我正在尝试找到 Room 的跟踪器来归档...
当心!至于房间 alpha4 版本,这种技术将导致 gradle 构建失败:issuetracker.google.com/issues/63608092
Ids
怎么样?我确实喜欢这样,但表 ID 继续增加。在真正的表 drop 中,id 也被删除,重新从 0 开始。
@yigit 有没有办法查出查询是成功运行还是出错了?【参考方案2】:
如果想从 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(); 【参考方案3】:从1.1.0
房间开始,您可以使用clearAllTables(),其中:
从作为entities()注册到该数据库的所有表中删除所有行。
【讨论】:
小心:clearAllTables() 是异步的,无法判断它何时完成。 @Alexey 但在 clearAllTables 之后尝试保存某些内容会不会有任何问题?如在,它只会尝试在清除后插入吗?因为我觉得很好。 @FirstOne clearAllTables 基本上只是在新的后台线程上启动事务。它从表中删除所有数据,然后提交该事务。如果您开始交易的时间晚于 clearAllTables 开始,那您很好。话虽如此,如果您尝试在调用 clearAllTable 之后立即插入一些数据,您的插入可能会在 clearAllTable 开始事务之前开始,您将丢失所有数据。如果需要在调用 clearAllTable 后立即插入新数据,至少要增加一些延迟。 @Alexey 有没有办法使用回调方法或类似方法来确定删除事务的状态?换句话说,如果删除事务状态已完成,则继续插入数据方法。 @AJW 不,到目前为止,仍然无法判断操作何时完成。如果你真的需要这个功能,你可能想试试SELECT name FROM sqlite_master WHERE type='table'
,然后手动DELETE FROM TABLE
。不过还没有测试过。【参考方案4】:
结合Dick Lucas 所说的内容并从其他 *** 帖子中添加重置自动增量,我认为这可以工作:
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 重新实例化并重新填充数据库。访问。 什么是 sqlite_sequence?【参考方案5】:将clearAllTables() 与RXJava 一起使用,如下所示,以避免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());
);
【讨论】:
【参考方案6】:我在使用 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)
【讨论】:
当你使用 Kotlin 时,你可以直接将其包裹在thread
中,而不是使用 RxJava 来搞砸【参考方案7】:
要在不滥用@Query
注释的情况下使用Room,首先使用@Query
选择所有行并将它们放在一个列表中,例如:
@Query("SELECT * FROM your_class_table")
List`<`your_class`>` load_all_your_class();
将他的列表放入delete注解中,例如:
@Delete
void deleteAllOfYourTable(List`<`your_class`>` your_class_list);
【讨论】:
【参考方案8】:这是我在 Kotlin 中的做法。
使用 DI (Koin) 在活动中注入 room db。
private val appDB: AppDB by inject()
然后你可以简单地调用 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)
【讨论】:
【参考方案9】:这就是我们从 Fragment 执行此操作的方式。
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 无法将调用识别为挂起函数。
【讨论】:
【参考方案10】:如果有人要删除所有表格,请刷新应用程序中的所有内容,无需任何代码跟随 Device File Explorer -> data -> data -> com.YOUR_APP -> databases
你可以删除databases
文件夹中的文件
【讨论】:
完美,谢谢!【参考方案11】:如果您使用的是Rx
,您可以这样做。
@Query("DELETE FROM yourDB")
void delete(); : Completable
【讨论】:
【参考方案12】:关于你的数据库实例调用
clearAllTables()
【讨论】:
你的回答和几年前回答的***.com/a/49545016/4744263有什么区别?以上是关于房间持久性库。删除所有的主要内容,如果未能解决你的问题,请参考以下文章