Android房间使用关系搜索和过滤,查询多个表

Android房间使用关系搜索和过滤,查询多个表,android,sql,android-room,Android,Sql,Android Room,回购协议如下,如果您想发出拉取请求,请包括评论 我已经为我的pokemonap创建了一个房间数据库,我希望能够根据Pokemon名称和Pokemon类型过滤和搜索数据库 我有一个用于Pokemon实体的表,一个用于PokemonType实体的表和一个用于PokemonTypeJoin实体的连接表,我还有一个数据类PokemonWithTypes,它嵌入了一个Pokemon实体,并定义了它与PokemonType实体列表之间的关系 口袋妖怪实体: @TypeConverters(RoomS

回购协议如下,如果您想发出拉取请求,请包括评论

我已经为我的pokemonap创建了一个房间数据库,我希望能够根据Pokemon名称和Pokemon类型过滤和搜索数据库

我有一个用于Pokemon实体的表,一个用于PokemonType实体的表和一个用于PokemonTypeJoin实体的连接表,我还有一个数据类PokemonWithTypes,它嵌入了一个Pokemon实体,并定义了它与PokemonType实体列表之间的关系

口袋妖怪实体:

    @TypeConverters(RoomStringListConverter::class)
    @Entity
    data class Pokemon(
        @NotNull
        @PrimaryKey
        @ColumnInfo(name = POKEMON_ID)
        var id: Int,
    
        @ColumnInfo(name = POKEMON_NAME)
        var name: String,
    
        @ColumnInfo(name = POKEMON_URL)
        var url: String,
    
        @ColumnInfo(name = POKEMON_WEIGHT)
        val weight: Int,
    
        @ColumnInfo(name = POKEMON_HEIGHT)
        val height: Int,
    
        @ColumnInfo(name = POKEMON_SPECIES)
        var species: String,
    
        @ColumnInfo(name = POKEMON_MOVES)
        val moves: List<String>
    
    ) 

    const val POKEMON_ID: String = "pokemon_id"
    const val POKEMON_NAME: String = "pokemon_name"
    const val POKEMON_URL: String = "pokemon_url"
    const val POKEMON_HEIGHT: String = "pokemon_height"
    const val POKEMON_WEIGHT: String = "pokemon_weight"
    const val POKEMON_MOVES: String = "pokemon_moves"
    const val POKEMON_SPECIES: String = "pokemon_species"
口袋妖怪加入实体:

    @Entity(primaryKeys = [POKEMON_ID, POKEMON_TYPE_ID])
    class PokemonTypesJoin(
        @NotNull
        @ColumnInfo(name = POKEMON_ID, index = true)
        val pokemon_id: Int,
    
        @NotNull
        @ColumnInfo(name = POKEMON_TYPE_ID, index = true)
        val pokemon_type_id: Int
    
    )
    
    const val POKEMON_ID: String = "id"
    const val POKEMON_TYPE_ID: String = "type_id"
口袋妖怪类

    data class PokemonWithTypes(
        @Embedded
        val pokemon: Pokemon,
        @Relation(
            parentColumn = Pokemon.POKEMON_ID,
            entity = PokemonType::class,
            entityColumn = PokemonType.POKEMON_TYPE_ID,
            associateBy = Junction(
                value = PokemonTypesJoin::class,
                parentColumn = PokemonTypesJoin.POKEMON_ID,
                entityColumn = PokemonTypesJoin.POKEMON_TYPE_ID
            )
        )
        val types: List<PokemonType>
    )
我现在得到了所有的口袋妖怪,可以通过口袋妖怪的名字来搜索,但我希望能够只显示水的类型或草的类型欢迎任何想法

我试着只过滤一个字符串,而不是像这样的查询字符串列表

@Transaction
@Query("SELECT * FROM pokemon, pokemonType WHERE type_name LIKE :filter AND pokemon_name LIKE :search ORDER BY pokemon_id ASC")
fun getPokemonWithTypes(search: String?, filter: String): LiveData<List<PokemonWithTypes>>
@事务
@查询(“从pokemon、pokemonType中选择*,其中键入\u name LIKE:filter和pokemon\u name LIKE:search ORDER BY pokemon\u id ASC”)
有趣的getPokemonWithTypes(搜索:String?,过滤器:String):LiveData
但它不起作用


您可以在这里查看完整内容

我认为@Relation注释不是为该用例设计的。它仅用于返回所有相关类型,而不是经过筛选的子集。我认为你有3个选择:

  • 只需使用Kotlin进行过滤:
    pokemonWithTypes.filter{it.types.contains(“GRASS”)}
    。我假设你没有超过10000条口袋妖怪的记录,所以性能不是问题
  • 编写一个连接查询。我认为这是为了获得微不足道的性能增益而付出的更多努力
  • 根据使用数据库视图:。这是更静态的,您必须为每种类型编写一个视图

  • 谢谢,我将在视图模型中对其进行筛选。他们需要帮助-->
    @Transaction
    @Query("SELECT * FROM pokemon WHERE pokemon_name LIKE :search ORDER BY pokemon_id ASC")
    fun getPokemonWithTypes(search: String?): LiveData<List<PokemonWithTypes>>
    
    PokemonWithTypes(pokemon=Pokemon(id=1, name=bulbasaur, types=[PokemonType(id=4, name=poison, slot=2), PokemonType(id=12, name=grass, slot=1)])
    PokemonWithTypes(pokemon=Pokemon(id=4, name=charmander, types=[PokemonType(id=10, name=fire, slot=2), PokemonType(id=12, name=grass, slot=1)])
    PokemonWithTypes(pokemon=Pokemon(id=7, name=squirtle, types=[PokemonType(id=11, name=water, slot=2), PokemonType(id=12, name=grass, slot=1)])
    
    @Transaction
    @Query("SELECT * FROM pokemon, pokemonType WHERE type_name LIKE :filter AND pokemon_name LIKE :search ORDER BY pokemon_id ASC")
    fun getPokemonWithTypes(search: String?, filter: String): LiveData<List<PokemonWithTypes>>