Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/188.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Android Room中获取所有子实体的正确方法是什么?_Android_Android Room - Fatal编程技术网

在Android Room中获取所有子实体的正确方法是什么?

在Android Room中获取所有子实体的正确方法是什么?,android,android-room,Android,Android Room,假设我在城市和人之间有一对多的关系 @实体(tableName=“city”) 数据级城市( @主键 val cityId:Int, val名称:String ) @实体(tableName=“person”) 数据类人员( @PrimaryKey(自动生成=真) val personId:Long=0, val name:String, val cityId:Int ) 目标是获取数据库中的所有人及其对应的城市。根据Jetpack文档,最明显的方法是创建一个citywhithpersons类

假设我在
城市
之间有一对多的关系

@实体(tableName=“city”)
数据级城市(
@主键
val cityId:Int,
val名称:String
)
@实体(tableName=“person”)
数据类人员(
@PrimaryKey(自动生成=真)
val personId:Long=0,
val name:String,
val cityId:Int
)
目标是获取数据库中的所有人及其对应的城市。根据Jetpack文档,最明显的方法是创建一个
citywhithpersons

data class CityWithPersons(
    @Embedded
    val city: City,
    @Relation(parentColumn = "cityId", entityColumn = "cityId")
    val persons: List<Person>
)
数据类城市有人(
@嵌入
瓦尔城:城市,
@关系(parentColumn=“cityId”,entityColumn=“cityId”)
val人员:名单
)
获取所有包含人员的城市,然后从那里合并人员

但在我的场景中,数据库中可能只有不到10个人和1000多个城市。这样做似乎很可笑,效率也很低

其他可能的办法可以是:

  • 获取完整的人员列表,然后使用
    cityId
    逐个查询城市
  • 城市
    嵌入
    个人
    实体,而不是
    城市ID
  • 多对多的关系
    PersonWithCity
    将只有一个带有一个实体的
    cities
    数组
我想知道哪种方法最好?还是我没想到的更好的方法

我想知道哪种方法最好?还是我没想到的更好的方法

我不相信多对多关系会带来任何性能优势,因为您仍然需要搜索其中一个表。我也不认为获得完整的人员列表,然后使用cityId逐个查询城市会有好处(但是你需要吗?(修辞性)查看一次就可以有效完成这一任务的人员和城市)

显而易见的方法是创建一个CityWithPersons类

既然你是从人的角度来看待这个问题,那么为什么不选择城市阶级的人呢

将城市嵌入个人实体而不是城市ID:-

还有一把刀,比如:-

@Query("SELECT * FROM person")
fun getPersonWithCity(): List<PersonWithCity>
还有一把刀,比如

@Query("SELECT *, city.name AS cityName FROM person JOIN city ON person.cityId = city.cityId")
fun getPersonAndCity(): List<PersonAndCity>
  • 请注意,我在两次运行之间卸载了应用程序

很抱歉回复太晚。到现在为止,我一直在分心这个项目。谢谢你清楚地解释了答案!
PersonWithCity
PersonAndCity
都可以工作。
data class PersonAndCity(

    val personId: Long,
    val name: String,
    val cityId: Int,
    val cityName: String,

)
@Query("SELECT *, city.name AS cityName FROM person JOIN city ON person.cityId = city.cityId")
fun getPersonAndCity(): List<PersonAndCity>
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val db = Room.databaseBuilder(applicationContext,MyDatabase::class.java,"Mydb")
            .allowMainThreadQueries()
            .build()
        val dao = db.getAllDao()
        val people = 10
        val cities = 1000
        for(i in 1..cities) {
            dao.insertCity(City(null,"City00" + i))
        }
        for(i in 1..people) {
            dao.insertPerson(Person(null,"Person" + i,(1..cities).random()))
        }
        val TAG = "CITYPERSONINFO"
        Log.d(TAG,"Starting Test 1 - Using CityWithPerson")
        val usingCityWithPerson = dao.getCityWithPerson()
        Log.d(TAG,"Done Test 1. Rows Extracted = " + usingCityWithPerson.size)
        Log.d(TAG,"Starting Test 2 - UsingPersonAndCity")
        val usingPersonWithCity = dao.getPersonWithCity()
        Log.d(TAG,"Done Test 2. Rows Extracted = " + usingPersonWithCity.size)
        Log.d(TAG,"Starting Test 3 - UsingPersonAndCity (no @Relation just JOIN)")
        val usingPersonAndCity = dao.getPersonAndCity()
        Log.d(TAG,"Done Test 3. Rows Extracted = " + usingPersonAndCity.size)

    }
}