RxJava + Android + GreenDao:级联删除多个实体

时间:2017-07-17 04:04:44

标签: android rx-java

我在数据库,课程和讲座中有2个表。他们是1:N的关系。我的问题是我想删除多个课程,在此之前我必须确保删除所有相关讲座,以及一些文件和讲座。也就是说,我想删除多个课程,对于每个课程,应执行以下步骤:

  1. 删除讲座文件并记录删除课程
  2. 删除课程
  3. 如何使用RxJava 1.x做到这一点?感谢。

2 个答案:

答案 0 :(得分:0)

我认为会是这样的:

    ArrayList<Course> courses = new ArrayList<>();
    Observable.fromIterable(courses)
            .doAfterNext(new Consumer<Course>() {
                @Override
                public void accept(Course course) throws Exception {
                    //DELETE this Course
                }
            }).flatMap(new Function<Course, ObservableSource<ArrayList<Lecture>>>() {
                @Override
                public ObservableSource<ArrayList<Lecture>> apply(Course course) throws Exception {
                    return Observable.fromArray(course.getAllLecture());
                }
            })
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Consumer<ArrayList<Lecture>>() {
                @Override
                public void accept(ArrayList<Lecture> lectures) throws Exception {
                    //delete all lectures
                }
            });

答案 1 :(得分:0)

如果你正在使用GreenDao,我不认为以这种方式使用RxJava是你最好的选择。这里的主要问题是您不在事务中,这会使您的数据最终处于不一致状态。虽然这可以是一个很好的练习,但“我怎样才能用Rx风格编写这段代码?”我建议在这个过程的每一步中都不会使用它。因此,我建议您将删除代码编写为GreenDao事务中的程序(而非Rx)代码,并仅在完成时使用RxJava进行通知。当你在GreenDao事务块中时,它内部的所有数据库调用都是以保证顺序一个接一个地同步进行的。

此外,为了获得最大的一致性,我会在提交事务块之后立即删除所有文件(因为如果部分数据库事务失败并且数据库不存在,您可能不想删除文件更新)。此外,在GreenDao中有两种主要的删除方式:直接,session.delete(entity)和查询,query.buildDelete().tableDeleteQuery.executeDeleteWithoutDetachingEntities()。直接删除对代码来说要简单得多,但如果你有大量的数据可能会更慢。如果您的实体少于1000个,那么直接删除可能就足够了。 所以,你的代码可能如下所示:

final DaoSession daoSession = getDaoSession();
final List<Course> courses = getCoursesToDelete();
// rxTx() creates a tx that runs on RxJava's 'io' scheduler.
daoSession.rxTx().call(() -> {
    List<File> filesToDelete = new ArrayList<>();
    for(Course course : courses) {
        for(Lecture lecture : course.getLectures()) {
            filesToDelete.add(lecture.getFiles());
            daoSession.delete(lecture);
        }
        daoSession.delete(course);
    }
    return filesToDelete;
})
// potentially handle DB errors here
// .flatMapIterable here if you want each File as an Rx event
.doOnNext(filesToDelete -> {
    for(File f : filesToDelete) {
        // Throw on failed delete here if needed
        f.delete();
    }
})
// handle file delete errors if desired.
.subscribeOn(Schedulers.io()) // technically redundant
.observeOn(AndroidSchedulers.mainThread())
.subscribe();