使用rxjava2查询单个数据库行

时间:2017-02-27 15:43:12

标签: rx-android rx-java2

我第一次在Android项目上使用rxjava2,并且正在后台线程上进行SQL查询。

但是,我无法找出执行简单SQL查询的最佳方法,并且能够处理记录可能存在或不存在的情况。这是我正在使用的代码:

public Observable<Record> createRecordObservable(int id) {
    Callable<Record> callback = new Callable<Record>() {
        @Override
        public Record call() throws Exception {
            // do the actual sql stuff, e.g.
            // select * from Record where id = ?
            return record;
        }
    };
    return Observable.fromCallable(callback).subscribeOn(Schedulers.computation());
}

当存在记录时,这很有效。但是在不存在与id匹配的记录的情况下,它将其视为错误。显然这是因为rxjava2不允许Callable返回null。

显然我并不是真的想要这个。只有在数据库失败或其他情况下才会出错,而空结果完全有效。我在某处读到一个可能的解决方案是将Record包装在Java 8 Optional中,但我的项目不是Java 8,无论如何这个解决方案看起来有点难看。

这肯定是一项常见的日常任务,我确信必须有一个简单易行的解决方案,但到目前为止我找不到一个。这里使用的推荐模式是什么?

2 个答案:

答案 0 :(得分:3)

您的用例似乎适用于发出1或0项的RxJava2新Observable类型Maybe
Maybe.fromCallable会将返回的null视为没有发出的项目。

你可以看到有关RxJava2的空值的this讨论,我想在你需要空值/空值的其他情况下,没有多少选择,但是使用Optional

答案 1 :(得分:0)

感谢@yosriz,我让它与Maybe合作。由于我无法在评论中添加代码,因此我将在此处发布完整的答案:

而不是Observable,使用Maybe就像这样:

public Maybe<Record> lookupRecord(int id) {
    Callable<Record> callback = new Callable<Record>() {
        @Override
        public Record call() throws Exception {
            // do the actual sql stuff, e.g.
            // select * from Record where id = ?
            return record;
        }
    };
    return Maybe.fromCallable(callback).subscribeOn(Schedulers.computation());
}

好处是返回的记录允许为空。要检测订户中发生的情况,代码如下:

lookupRecord(id)
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Consumer<Record>() {
            @Override
            public void accept(Record r) {
                // record was loaded OK

            }
        }, new Consumer<Throwable>() {
            @Override
            public void accept(Throwable throwable) {
                // there was an error

            }
        }, new Action() {
            @Override
            public void run() {
                // there was an empty result
            }
        });