我正在试图弄清楚如何处理Room的错误。我有以下在数据库中插入任务的交互器:
TaskInteractor.java
public class TaskInteractor extends AbstractInteractor implements TaskContract.Interactor {
final TaskRepository mRepository;
interface Callback {
void onSuccess();
void onFailure(Throwable t);
}
@Inject
public TaskInteractor(WorkerThread workerThread,
MainThread mainThread,
TaskRepository repository) {
super(workerThread, mainThread);
this.mRepository = repository;
}
@Override
public void insertTask(final Task task, final Callback callback)
throws SQLiteException {
mWorkerThread.get().execute(new Runnable() {
@Override
public void run() {
try {
mRepository.insertTask(task);
} catch (SQLiteException exeption) {
Timber.e("Insertion failed. Exception: " + exeption.getMessage());
callback.onFailure(exeption);
throw exeption;
}
Timber.d("Insertion succeeded.");
callback.onSuccess();
}
});
}
}
在insertTask
中,我使用try-catch块来检查SQLiteException
是否发生了。如果是,我抛出异常。
但这是处理错误的好方法还是有更好的方法?
答案 0 :(得分:0)
如果是,我抛出异常。但这是一种很好的处理方式 错误还是有更好的方法?
这在很大程度上取决于您要做什么以及基础架构。
例如,如果您只想知道插入是否成功,则(假设您未使用外键)然后在 @Insert中使用 onConflict (可选)以及使用从插入中返回的值(即 rowid 作为长整数)可以毫无例外地产生相同的结果。
例如,考虑以下实体:-
@Entity(tableName = "item")
public class Item {
@PrimaryKey
@NonNull
@ColumnInfo(name = "item_id")
private String item_id;
@ColumnInfo(name = "description")
private String description;
@ColumnInfo(name = "price")
private double price;
...........
}
唯一不起作用的插入是 item_id 为空或现有 item_id
的插入使用:-
中的任何一个@Insert
void insertItem(Item item);
@Insert
void insertItems(Item... items);
如果尝试插入item_id为null或现有item_id的行,则将导致异常
但是,使用
@Insert(onConflict = OnConflictStrategy.IGNORE)
long insertItem(Item item);
@Insert(onConflict = OnConflictStrategy.IGNORE)
long[] insertItems(Item... items);
不会导致异常,因为基础SQL有效地是INSERT或IGNORE,此外,将返回行号(对于后者),然后可以对其进行查询。
首先,如果返回的rowid小于1,则未插入该行。
在第二个步骤中,您将根据对象列表插入行,您可以检查返回数组的每个元素,以查看哪些插入和哪些未插入。因此,在第二个示例中,无需处理异常。
但是,如果涉及外键,则该异常是不可捕获的。通过检查父列是否存在(在插入之前)可以防止它们发生
与外键的进一步复杂化可能是处理父级的更新/删除。这些可以通过利用onUpdate / onDelete(通常通过指定CASCADE)来缓解。 :-
@Entity(tableName = "invoice",
foreignKeys = {
@ForeignKey(
entity = Item.class,
parentColumns = "item_id",childColumns = "item_reference",onDelete = ForeignKey.CASCADE, onUpdate = ForeignKey.CASCADE)},
indices = {@Index(value = "item_reference")}
)
.........
但这是处理错误的好方法还是有更好的方法 方式吗?
由于答案是基于意见的,因此无法真正给出答案,而是经常有使用异常处理的替代方法。已经显示了一些。