Android房间条件查询IN和NULL

pcww981p  于 2022-12-25  发布在  Android
关注(0)|答案(2)|浏览(235)

我有复杂的Android房间查询:

SELECT * FROM Model WHERE (:applyAssigneeFilters IS 0 OR assigneeMemberId IN(:assigneeFilters))...

我正在传递boolean-applyAssigneeFilters,以确定查询是否应返回assigneeFilters列表中assigneeMemberId所在的项。
这工作得很好,但是,现在我有新的要求,包括项目是未分配。
我想有类似的选项(bool值),将过滤项目的assigneeMemberId和/或isAssigneed。这两个选项可以组合。
编辑:
在UI侧,我有选项列表:

[] Unassigned
[] Member1
[] Member2

在添加"未分配"选项之前,applyAssigneeFilters变量只是一个assigneeFilters.isEmpty()检查。添加Unassigned之后,我只需要过滤Unassigned项或/和assigneeFilters中分配的成员。
示例:给定项目:

Item(id: 1, memberId: 1, unassigned: false)
Item(id: 2, memberId: 2, unassigned: false)
Item(id: 3, memberId: null, unassigned: true)

和选项

[X] Unassigned
[] Member1
[] Member2

结果将是:

Item(id: 3, memberId: null, unassigned: true)

对于选项:

[X] Unassigned
[] Member1
[X] Member2

结果将是:

Item(id: 2, memberId: 2, unassigned: false)
Item(id: 3, memberId: null, unassigned: true)

对于选项:

[] Unassigned
[X] Member1
[X] Member2

结果将是:

Item(id: 1, memberId: 1, unassigned: false)
Item(id: 2, memberId: 2, unassigned: false)
omjgkv6w

omjgkv6w1#

根据你的例子,你可以简单地用途:

@Query("SELECT * FROM Model WHERE unassigned=:applyAssigneeFilters OR memberId IN(:assigneeFilters);")
    fun getModelsByFilter(applyAssigneeFilters: Boolean, assigneeFilters: List<Long>): List<Model>
  • 这确实假设了false和true或者实际上存储为0和NOT 0而不是文本值,就像在所提供的SQL中比较0时出现的情况一样。

下面是一个生成结果的工作示例:
使用的数据库材料:-

@Entity
data class Model(
    @PrimaryKey
    var id: Long?=null,
    var memberId: Long?,
    var unassigned: Boolean
)
@Database(entities = [Model::class], exportSchema = false, version = 1)
abstract class TheDatabase: RoomDatabase() {
    abstract fun getAllDAOs(): AllDAOs

    companion object {
        private var instance: TheDatabase?=null
        fun getInstance(context: Context): TheDatabase {
            if (instance==null) {
                instance = Room.databaseBuilder(context,TheDatabase::class.java,"the_database")
                    .allowMainThreadQueries()
                    .build()
            }
            return instance as TheDatabase
        }
    }
}
@Dao
interface AllDAOs {
    @Insert(onConflict = OnConflictStrategy.IGNORE)
    fun insert(model: Model)
    @Query("SELECT * FROM Model WHERE unassigned=:applyAssigneeFilters OR memberId IN(:assigneeFilters);")
    fun getModelsByFilter(applyAssigneeFilters: Boolean, assigneeFilters: List<Long>): List<Model>
}

活动的布局,包含3个复选框(未分配、成员1和成员2)、一个用于GO并获取结果的按钮以及一个用于显示结果的TextView:-

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        >
    </TextView>

    <CheckBox
        android:id="@+id/unassigned"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Unassigned" />

    <CheckBox
        android:id="@+id/member1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Member1" />

    <CheckBox
        android:id="@+id/member2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Member2" />

    <Button
        android:id="@+id/go"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="GO"
        >
    </Button>

    <TextView
        android:id="@+id/resultant_data"
        android:layout_width="match_parent"
        android:layout_height= "500dp"
        >
    </TextView>
</LinearLayout>

活动代码:-

class MainActivity : AppCompatActivity() {
    lateinit var db: TheDatabase
    lateinit var dao: AllDAOs
    lateinit var unassigned: CheckBox
    lateinit var member1: CheckBox
    lateinit var member2: CheckBox
    lateinit var goButton: Button
    lateinit var resultantData: TextView
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        unassigned = this.findViewById(R.id.unassigned)
        member1 = this.findViewById(R.id.member1)
        member2 = this.findViewById(R.id.member2)
        goButton = this.findViewById(R.id.go)
        resultantData = this.findViewById(R.id.resultant_data)

        db = TheDatabase.getInstance(this)
        dao = db.getAllDAOs()

        dao.insert(Model(1,1,false))
        dao.insert(Model(2,2,false))
        dao.insert(Model(3,null,true))

        goButton.setOnClickListener { doit()}

    }

    fun doit() {
        val assigneeFilter = ArrayList<Long>()
        val sb = StringBuilder()
        if (member1.isChecked) assigneeFilter.add(1)
        if (member2.isChecked) assigneeFilter.add(2)
        for(m in dao.getModelsByFilter(unassigned.isChecked,assigneeFilter)) {
            if (sb.length > 0) sb.append("\n")
            sb.append("ID=${m.id} MEMBERID=${m.memberId} UNASSIGNED=${m.unassigned}")
        }
        resultantData.text = sb
    }
}

结果:-
第一次运行时(未显示):-

如果随后点击Go(未选中任何内容,即所有内容均未分配,结果与第3个示例相同(这是您想要的吗?)):-

复选框符合第一个示例:-

第二个示例中的复选框:-

第三个示例中的复选框:-

数据库中的数据(通过应用程序检查):-

cidc1ykv

cidc1ykv2#

我找到了解决自己问题的办法。

(:applyAssigneeFilters IS 0 OR (assigneeMemberId IN(:assigneeFilters) OR (:unassignedMemberId IN(:assigneeFilters) AND hasAssignee IS 0)))

因此,我引入了unassignedMemberId,它被添加到assigneeFilters列表中,并且模型已经具有字段hasAssignee,这允许我在没有受让人的情况下过滤项目,并且仍然使用applyAssigneeFilters标志。

相关问题