简体   繁体   English

如何在Room数据库中进行事务操作删除部分表 android

[英]How to perform transaction operation in Room database to delete some tables android

I am not familiar with Room Database.我不熟悉房间数据库。 I want to clear the data from some tables when I click on button.我想在单击按钮时清除某些表中的数据。 I have the similar code in IOS but I am not sure where I have to write this method and call this delete function and how to access the tables.我在 IOS 中有类似的代码,但我不确定必须在哪里编写此方法并调用此 delete function 以及如何访问表。 Can anyone help me on this in android.任何人都可以在 android 中帮助我解决这个问题。

IOS code: IOS 代码:

class ApplicationResetManager: NSObject {
    
    static let shared: ApplicationResetManager = ApplicationResetManager()
    var cloSuccess:((_ isSuccessfull: Bool)->Void)?
    
    func clearAllData(completion: (Bool) -> Void) {
        let isSyncGoingOn = ApplicationManager.shared.isSyncGoingOn
        if let currentUser = ApplicationManager.shared.currentUser, currentUser.id! > 0, isSyncGoingOn == false {
            let dbQueue = DatabaseManager.shared.dbQueue!
            do {
                // 4. Access the database
                try dbQueue.inTransaction { db in
                    do {
                        try UserLocations.deleteAll(db)
                        try LineLayoutEquipment.deleteAll(db)
                        try LineLayout.deleteAll(db)
                        try Survey.deleteAll(db)
                        try HealthCheck.deleteAll(db)
                        try HealthCheckData.deleteAll(db)
                        try ActionItem.deleteAll(db)
                        try Equipments.deleteAll(db)
                        try EquipmentIndustry.deleteAll(db)
                        try Comments.deleteAll(db)
                        try PlantAreas.deleteAll(db)
                        try PlantAreasIndustrys.deleteAll(db)
                        try Applications.deleteAll(db)
                        try ApplicationsIndustrys.deleteAll(db)
                        try SurveyLineLevel.deleteAll(db)
                        try HealthCheckLineLevel.deleteAll(db)
                        try ActionItemLineLevel.deleteAll(db)
                        try ActionItemLineLvlComments.deleteAll(db)
                        
                        UserDefaults.standard.set([], forKey: arr_selected_company)
                        ApplicationManager.shared.currentUser.defaultCompanyId = nil
                        completion(true)
                        return .commit
                    } catch {
                        completion(false)
                        return .rollback
                    }
                }
            } catch {
                completion(false)
            }
        } else {
            print("Sync is already in progress")
        }
    }
}

If using Room you would have如果使用 Room 你会有

  1. @Entity annotated classes (the tables), @Entity注释类(表),

  2. a single @Database annotated class per database (very probably just the 1) that:-每个数据库(很可能只是第一个)注释为 class 的单个@Database :-

    1.describes the database (list of entities (ie tables aka @Entity annotated class(es)) via the entities parameter) 1.通过entities参数描述数据库(实体列表(即表又名@Entity注释类))

    1. provides abstract methods for obtaining the @Dao annotated (interface(s) or abstract class(es))提供用于获取@Dao注释的抽象方法(接口或抽象类)
  3. One or more @Dao annotated interfaces and/or abstract classes which一个或多个@Dao注释接口和/或抽象类

    1. detail the convenience methods ( @Insert , @Delete , @Update ) and @Query methods.详细介绍便捷方法( @Delete 、@ @Query @Update @Insert

As you appear to want to do many things in a single transaction, the you would want a method that invokes those many actions.由于您似乎想在单个事务中做很多事情,因此您需要一个调用这些许多操作的方法。

An interface cannot have methods with functions, therefore you would need an @Dao annotated class.接口不能有带函数的方法,因此您需要一个带注释的@Dao class。

The actual, do many things method is a little bit of a trick.实际上,do many things 方法有点小技巧。

You first of all have an @Transaction annotation.您首先有一个@Transaction注释。 As room doesn't appear to consider this annotation unless you are using one of the annotations (and the only one that can be tailored is @Query ), then you tell Room to run a query that does nothing ie use @Query("") .由于 room 似乎不考虑此注释,除非您使用注释之一(并且唯一可以定制的注释是@Query ),然后您告诉 Room 运行一个不执行任何操作的查询,即使用@Query("")

The you define the method with the body that can invoke other methods in the @Dao annotated abstract class.您定义方法的主体可以调用@Dao注释摘要 class 中的其他方法。

So you your code could be along the lines of:-所以你的代码可能是这样的:-

@Dao
abstract class MyDoitAllStuffDao {
    @Query("DELETE FROM userLocations") /* no WHERE clauses = delete all rows. TO BE USED IN DO IT ALL METHOD*/
    int deleteAllUserLocations();

    @Query("DELETE FROM linelayoutequipment");
    int deleteAllLineLayoutEquipment();
    
    ....

    @Transaction
    @Query("") /* trick room into think it is doing something */
    void /* or some useful return type */ doLotsOfThingsInASingleTransaction() {
    .... if you want to do preparotory stuff
    int deleteAllUserLocations_count = deleteAllUserLocations();
    int deleteAllLineLayout_count = deleteAllLineLayoutEquipment();

    .... etc
   }
}

Then somewhere in you code you get an instance @Database abstract class with the RoomDatabase built and then retrieve and then invoke the appropriate method ( doLotsOfThinsInASingleTransaction ) after getting the respective @Dao annotated interface/class instance via the abstract method in the @Database annotated abstract class.然后在你的代码中的某个地方你得到一个实例@Database abstract class 构建了 RoomDatabase 然后检索然后调用适当的方法( doLotsOfThinsInASingleTransaction )通过@Database注释抽象中的抽象方法获取相应的@Dao注释接口/类实例class。

Here's an example (not run but compiled successfully)这是一个示例(未运行但编译成功)

A few @Entity annotated classes (very basic as it's not about the complexity/design of tables):-一些@Entity注释类(非常基本,因为它与表的复杂性/设计无关):-

@Entity
class UserLocations {
    @PrimaryKey Long id=null;
    String user_name;
}

@Entity
class LineLayoutEquipment {
    @PrimaryKey Long id=null;
    String lle_name;
}
  • obviously your classes will very likely differ, that is not relevant显然你的课程很可能会有所不同,那是不相关的

The @Dao annotated abstract class (rather than the more typical interface (abstract class is more flexible due to methods with bodies)):- @Dao注释的抽象 class(而不是更典型的接口(抽象 class 由于带有主体的方法更灵活)):-

@Dao
abstract class MyDoitAllStuffDao {

    @Query("DELETE FROM userLocations")
    abstract void deleteAllUserLocations();
    @Query("DELETE FROM linelayoutequipment")
    abstract void deleteAllLineLayoutEquipment();

    @Transaction
    @Query("")
    void doLotsOfThingsInASingleTransaction() {
        deleteAllUserLocations();
        deleteAllLineLayoutEquipment();
    }
}
  • I typically code these after the @Database annotated class, but makes more sense to include it before as the @Database annotated class, when complete requires the @Dao annotated class(es)我通常在@Database注释 class 之后编写这些代码,但在@Database注释 class 之前包含它更有意义,当完成时需要@Dao注释类

The @Database annotated abstract class (singleton):- @Database注释摘要 class(单例):-

@Database(
        entities = {UserLocations.class,LineLayoutEquipment.class},
        exportSchema = false,
        version = 1
)
abstract class TheDatabase extends RoomDatabase {
    abstract MyDoitAllStuffDao getMyDoitAllStuffDao();

    private static TheDatabase INSTANCE;
    static TheDatabase getInstance(Context context) {
        if (INSTANCE==null) {
            return Room.databaseBuilder(context,TheDatabase.class,"the_database.db")
                    .build();
        }
        return INSTANCE;
    }
}

Finally using the above in activity code eg :-最后在活动代码中使用上面的内容,例如:-

public class MainActivity extends AppCompatActivity {
    TheDatabase db;
    MyDoitAllStuffDao dao;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        db = TheDatabase.getInstance(this);
        dao = db.getMyDoitAllStuffDao();
        dao.doLotsOfThingsInASingleTransaction();

    }
}

So all you need to do is ensure you have instantiated the db and dao with scope for the Listener and use the last line (off the main thread though if following conventions).所以你需要做的就是确保你已经用 scope 为监听器实例化了 db 和 dao 并使用最后一行(如果遵循约定,则在主线程之外)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Android Room JUnit 测试:“AsyncTask #1” java.lang.IllegalStateException:无法执行此操作,因为当前没有事务 - Android Room JUnit testing: "AsyncTask #1" java.lang.IllegalStateException: Cannot perform this operation because there is no current transaction 如何通过Android中的Room删除数据库元数据? - How to delete database metadata via room in android? 如何使用 Rxjava 执行房间交易 - How to perform a room transaction usin Rxjava 如何在 Room Database 中一次查询删除两个表? - How to in Room Database delete two tables in one query? 如何用列表在数据库中删除房间表<collections> ?</collections> - How to write delete room tables in database with list<collections>? 带有两张表的 Android 房间数据库 - Android room database with two tables Android 房间数据库中的多个表 - Multiple Tables In Android Room Database Android房间数据库删除不起作用? - Android room database delete is not working? 想根据Android中不同的class对象在多个表中插入数据 Application using Room Database Library transaction - Want to Insert Data in multiple tables according to different class objects in Android Application using Room Database Library transaction 如何在下一版本的房间数据库Android中删除列? - How to delete column in next version of room database Android?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM