Android:使用Room和RxJava检查数据库中是否存在对象

Android:使用Room和RxJava检查数据库中是否存在对象,android,kotlin,rx-java,android-room,Android,Kotlin,Rx Java,Android Room,我使用Room作为ORM,下面是我的Dao界面: @Dao interface UserDao { @Query(value = "SELECT * FROM User LIMIT 1") fun get(): Single<User?> @Insert(onConflict = OnConflictStrategy.REPLACE) fun add(profile: User) } @Dao 接口用户DAO{ @查询(value=“选择*来自用户

我使用
Room
作为ORM,下面是我的Dao界面:

@Dao
interface UserDao {
    @Query(value = "SELECT * FROM User LIMIT 1")
    fun get(): Single<User?>

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun add(profile: User)
}
@Dao
接口用户DAO{
@查询(value=“选择*来自用户限制1”)
fun get():单身
@插入(onConflict=OnConflictStrategy.REPLACE)
趣味添加(个人资料:用户)
}
另一方面,我在存储库中有一个方法,可以检查用户是否登录,下面是实现代码:

override fun isUserLogin(): Single<Boolean> = userDao
            .get().async()
            .onErrorReturn { null }
            .map { it != null }
override fun isUserLogin():Single=userDao
.get().async()
.onErrorReturn{null}
.map{it!=null}
如果没有与查询匹配的行,文件室将引发以下异常:

查询返回空结果集:从用户限制1中选择*

在这种情况下,我想返回
null
,但是当我执行代码时,它会抛出一个异常,消息如下:

提供的值为空

我不能使用
Optional
,因为Dao正在返回
Single
,所以
onerrorrurn
应该返回相同的类型


如何在不更改Dao的情况下检查用户是否存在?

使用
Maybe
,它可以准确地模拟预期结果为0、结果为1或异常的响应。

如果更改Dao以返回可流动的用户列表,则可以通过检查列表的大小将其映射为布尔值

@Query(value = "SELECT * FROM User LIMIT 1")
fun get(): Flowable<List<User>> 
@Query(value=“选择*来自用户限制1”)
fun get():可流动
e、 g

fun isUserLogin():Single=userDao
.get()
.flatMapSingle{Single.just(it.size==1)}
.onErrorReturn{false}
.第一(错)

除了Android和Room之外,我认为正确的方法是在查询中使用
COUNT

@Query("SELECT COUNT(*) from User")
fun usersCount() : Single<Int>
@Query(“从用户选择计数(*))
fun userscont():单个
它将返回表中的行数,如果为0,则您知道数据库中没有用户,因此

override fun isUserLogin(): Single<Int> = userDao
            .usersCount()
            .async()
            .map { it > 0 }
override fun isUserLogin():Single=userDao
.userscont()
.async()
.map{it>0}
如果你真的想用丑陋的方式做这件事:

@Query(value = "SELECT * FROM User LIMIT 1")
fun get(): Single<User>
@Query(value=“选择*来自用户限制1”)
fun get():单身
不要使用可为null的类型,这是毫无意义的。然后映射到Boolean并处理异常:

override fun isUserLogin(): Single<Boolean> = userDao
        .get()
        .async()
        .map { true }
        .onErrorReturn { false }
override fun isUserLogin():Single=userDao
.get()
.async()
.map{true}
.onErrorReturn{false}

它抛出:MaybeSource为空,可能您正在执行的
toSingle
,根据定义,single不能为“empty”,因此这意味着空的
可能会变成错误条件
single
如果在DAO中使用single,则当数据库中没有记录时,文件室将始终抛出EmptyResultSetException-在这种情况下可能可以,因为onErrorReturn捕捉到这一点,但是,如果在不同的位置调用DAO,则需要处理错误。使用Flowable,您至少会返回一个结果集,如果没有记录,结果集将为空。如果您需要查询所有用户,那么使用
List
是有意义的,但是如果您只需要行数,我认为直接返回行数是最干净的做法。当您只需要计数时,查询用户模型是件麻烦事。
override fun isUserLogin(): Single<Boolean> = userDao
        .get()
        .async()
        .map { true }
        .onErrorReturn { false }