在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
@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)
}
}