Ale*_*dro 19 sqlite android persistence dao android-room
官方文件指出:
It is recommended to have multiple Dao classes in your codebase depending on the tables they touch.
Run Code Online (Sandbox Code Playgroud)
并且可以使用Transaction注释标记方法,如下所示:
@Dao
public abstract class ProductDao {
@Insert
public abstract void insert(Product product);
@Delete
public abstract void delete(Product product);
@Transaction
public void insertAndDeleteInTransaction(Product newProduct, Product oldProduct) {
// Anything inside this method runs in a single transaction.
insert(newProduct);
delete(oldProduct);
}
}
Run Code Online (Sandbox Code Playgroud)
但是,如果一个事务跨越多个DAO怎么办?我应该将所有DAO合并为一个只是为了支持交易,还是有更好的方法来做到这一点?
Mar*_*lin 21
您可以使用RoomDatabase.runInTransaction(...)
就像是:
database.runInTransaction(new Runnable(){
@Override
public void run(){
Access all your daos here
}
});
Run Code Online (Sandbox Code Playgroud)
事实 1: 在方法上使用 @Transaction 会导致该方法在 Dao_Impl 生成的类中被重写。这个方法看起来像这样:
@Override
public void makeFieldInactive(final long fieldId) {
__db.beginTransaction();
try {
MyDao_Impl.super.makeFieldInactive(fieldId);
__db.setTransactionSuccessful();
} finally {
__db.endTransaction();
}
}
Run Code Online (Sandbox Code Playgroud)
事实 2: runInTransaction() 方法如下所示:
/**
* Executes the specified {@link Runnable} in a database transaction. The transaction will be
* marked as successful unless an exception is thrown in the {@link Runnable}.
* <p>
* Room will only perform at most one transaction at a time.
*
* @param body The piece of code to execute.
*/
@SuppressWarnings("deprecation")
public void runInTransaction(@NonNull Runnable body) {
beginTransaction();
try {
body.run();
setTransactionSuccessful();
} finally {
endTransaction();
}
}
Run Code Online (Sandbox Code Playgroud)
结论: 他们都做同样的事情。
更多信息: 我已经做了一些测试,看来使用它们中的任何一个(或两者,冗余地)将成功地导致您的 you Dao 方法在一个事务中运行。
答: 在访问同一数据库的多个 Daos 中进行更改的方法上使用 @Transaction 是一种安全的方法,可以确保该方法中发生的所有数据库操作都发生在一个事务中。
编辑:在标有 @Transactoin 的一种方法中访问多个 Dao 的示例:
@Transaction
public void addItem(ItemEntity item) {
item.setId(insert(item));
ItemReportDao itemReportDao = AppDatabase.getIntance().itemReportDao();
itemReportDao.addItemReport(item.getId());
}
Run Code Online (Sandbox Code Playgroud)