简体   繁体   中英

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. Can anyone help me on this in android.

IOS code:

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

  1. @Entity annotated classes (the tables),

  2. a single @Database annotated class per database (very probably just the 1) that:-

    1.describes the database (list of entities (ie tables aka @Entity annotated class(es)) via the entities parameter)

    1. provides abstract methods for obtaining the @Dao annotated (interface(s) or abstract class(es))
  3. One or more @Dao annotated interfaces and/or abstract classes which

    1. detail the convenience methods ( @Insert , @Delete , @Update ) and @Query methods.

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.

The actual, do many things method is a little bit of a trick.

You first of all have an @Transaction annotation. 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("") .

The you define the method with the body that can invoke other methods in the @Dao annotated abstract 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.

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

The @Database annotated abstract class (singleton):-

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM