房间嵌套查询和子查询
Room nested query and subquery
我在我的 Android 项目中使用 Room,并且想编写一个复杂的查询。我搜索了一下,有一些答案 说使用 @Embedded 像这样:
class TripAndListsAndListItems {
@Embedded
var trip: Trip? = null
@Relation(parentColumn = "creatorId", entityColumn = "remoteId", entity = User::class)
var user: List<User>? = null
@Relation(parentColumn = "remoteId", entityColumn = "tripId", entity = PlanitiList::class)
var lists: List<ListAndListItems>? = null
}
但是我必须在我的代码中找出它来使用循环等提取我的结果。
我在 @Query 中使用嵌套查询编写查询,并使用“as”将列与实体字段匹配,如下所示:
这里是 ViewModel class:
class ServiceCard(
val id: Int,
val customerInfo: String,
val time: String,
val oilFilter: Boolean,
val airFilter: Boolean,
val gasFilter: Boolean,
val oil: Boolean
)
和@Doa有一个像这样的@Query方法:
@Dao
interface ServiceCardDao :ICommonDao<ServiceCard>{
@Query("SELECT s.services_id as id, " +
"s.user_mobile_no as customerInfo, " +
"( " +
"SELECT count(*) " +
"FROM service_detail as sd " +
"WHERE sd.services_id = s.services_id and sd.service_type_id = 1 " +
") as oilFilter, " +
"( " +
"SELECT count(*) " +
"FROM service_detail as sd " +
"WHERE sd.services_id = s.services_id and sd.service_type_id = 2 " +
") as airFilter, " +
"( " +
"SELECT count(*) " +
"FROM service_detail as sd " +
"WHERE sd.services_id = s.services_id and sd.service_type_id = 3 " +
") as gasFilter, " +
"( " +
"SELECT count(*) " +
"FROM service_detail as sd " +
"WHERE sd.services_id = s.services_id and sd.service_type_id = 4 " +
") as oil, " +
"s.service_date as time " +
"FROM services as s ")
fun selectAllServicesWithDetail(): LiveData<List<model.ServiceCard>>
}
这两个有什么优缺点吗?
两者各有优势。
一个在Dao中的编码更复杂,另一个在Entity中的编码更复杂,但Dao中的复杂度大于Entities的复杂度差异。所以简单的道可能会得到一些人的青睐。
一个会更有效,因为没有 post 数据检索循环来获取计数,此外 SQLite 是编译的 C 代码而不是必须解释的 JVM 字节码,因此 SQlite 通常非常有效。然而,效率很可能是一些人为了更简单的编码而愿意放弃的东西,也许是为了人们习惯的东西。
有些人可能会考虑将 Dao 和 Class 合为一体的替代方案,例如 DatabaseViews。
我在我的 Android 项目中使用 Room,并且想编写一个复杂的查询。我搜索了一下,有一些答案 说使用 @Embedded 像这样:
class TripAndListsAndListItems {
@Embedded
var trip: Trip? = null
@Relation(parentColumn = "creatorId", entityColumn = "remoteId", entity = User::class)
var user: List<User>? = null
@Relation(parentColumn = "remoteId", entityColumn = "tripId", entity = PlanitiList::class)
var lists: List<ListAndListItems>? = null
}
但是我必须在我的代码中找出它来使用循环等提取我的结果。 我在 @Query 中使用嵌套查询编写查询,并使用“as”将列与实体字段匹配,如下所示:
这里是 ViewModel class:
class ServiceCard(
val id: Int,
val customerInfo: String,
val time: String,
val oilFilter: Boolean,
val airFilter: Boolean,
val gasFilter: Boolean,
val oil: Boolean
)
和@Doa有一个像这样的@Query方法:
@Dao
interface ServiceCardDao :ICommonDao<ServiceCard>{
@Query("SELECT s.services_id as id, " +
"s.user_mobile_no as customerInfo, " +
"( " +
"SELECT count(*) " +
"FROM service_detail as sd " +
"WHERE sd.services_id = s.services_id and sd.service_type_id = 1 " +
") as oilFilter, " +
"( " +
"SELECT count(*) " +
"FROM service_detail as sd " +
"WHERE sd.services_id = s.services_id and sd.service_type_id = 2 " +
") as airFilter, " +
"( " +
"SELECT count(*) " +
"FROM service_detail as sd " +
"WHERE sd.services_id = s.services_id and sd.service_type_id = 3 " +
") as gasFilter, " +
"( " +
"SELECT count(*) " +
"FROM service_detail as sd " +
"WHERE sd.services_id = s.services_id and sd.service_type_id = 4 " +
") as oil, " +
"s.service_date as time " +
"FROM services as s ")
fun selectAllServicesWithDetail(): LiveData<List<model.ServiceCard>>
}
这两个有什么优缺点吗?
两者各有优势。
一个在Dao中的编码更复杂,另一个在Entity中的编码更复杂,但Dao中的复杂度大于Entities的复杂度差异。所以简单的道可能会得到一些人的青睐。
一个会更有效,因为没有 post 数据检索循环来获取计数,此外 SQLite 是编译的 C 代码而不是必须解释的 JVM 字节码,因此 SQlite 通常非常有效。然而,效率很可能是一些人为了更简单的编码而愿意放弃的东西,也许是为了人们习惯的东西。
有些人可能会考虑将 Dao 和 Class 合为一体的替代方案,例如 DatabaseViews。