Select 使用@Relation 同时从 Room 数据库中获取 3 个实体
Select 3 entities at once from Room Database with @Relation
我的应用程序中有一个数据库,它有 3 个表服务器、站点、组
@Entity(tableName = "servers")
data class Server(
@ColumnInfo(name = "server_id")
var serverId: Long,
@ColumnInfo(name = "account_id")
var accountId: Int,
@ColumnInfo(name = "device_id")
var deviceId: Int,
@ColumnInfo(name = "company_id")
var companyId: Int
.......
@Entity(tableName = "sites")
data class Site(
@ColumnInfo(name = "server_id")
var serverId: Long,
@ColumnInfo(name = "site_id")
val siteId: Int,
@ColumnInfo(name = "description", defaultValue = "")
val description: String
)
@Entity(tableName = "groups")
data class Group(
@ColumnInfo(name = "server_id")
val serverId: Long,
@ColumnInfo(name = "group_id")
var groupId: Int,
@ColumnInfo(name = "site_id")
val siteId: Int,
@ColumnInfo(name = "description", defaultValue = "")
val description: String
......
因此我们可以看到,对于每台服务器,我们都有站点,并且每个站点都有多个组。
现在我制作了一个名为 ServerSiteWithGroup 的 POJO,其中包含一个服务器和另一个 POJO SiteWithGroup
data class ServerSiteWithGroup(
@Embedded
val server: Server,
@Relation(parentColumn = "server_id", entityColumn = "server_id")
val siteWithGroup: SiteWithGroup
)
data class SiteWithGroup(
@Embedded
val group: Group,
@Relation(parentColumn = "site_id", entityColumn = "site_id")
val site: Site
)
鉴于我想对房间数据库进行一次查询并在给定 serverId, siteId, groupId
的情况下获取服务器、站点、组对象
我已经试过了,但是没用
@Transaction
@Query("Select * from groups
inner join servers on groups.server_id = servers.server_id
where groups.server_id = :serverId
and groups.site_id = :siteId
and groups.group_id = :groupId")
fun getSiteWithGroup(serverId: Long, siteId: Int, groupId: Int): LiveData<ServerSiteWithGroup>
我该如何解决这个问题?
首先,您似乎没有使用 @PrimaryKey 注释定义任何主键,这会导致编译错误。
其次,@Query 不应该 return LiveData<ServerSiteWithGroup>
但应该 return 一个 LiveData 数组,它们本身是(我相信)ServerSiteWithGroup 的数组,所以我认为应该 return =28=].
- 也许先试试这个 但是考虑一下 Even More 部分已经添加到答案结束。
.
How can i solve that problem?
- 您不mention/specify实际问题是什么。但是,以下是基于您提供的信息的解决方案。 (但为了方便没有使用
LiveData
)
在您拥有 ServerId 的群组实体中,这是不必要的,因为作为群组父级的站点将服务器作为其父级。这不是错误,但没有必要。
虽然理论上不需要,但 id 可以是 Long,因此我总是建议在关系中使用 Long 而不是 Int。
例子
这是一个基于您的代码的工作示例。
服务器
@Entity(tableName = "servers")
data class Server(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "server_id")
var serverId: Long?,
@ColumnInfo(name = "account_id")
var accountId: Int,
@ColumnInfo(name = "device_id")
var deviceId: Int,
@ColumnInfo(name = "company_id")
var companyId: Int
)
Primarykey
已定义。
autogenerate
和 Long?
允许生成 id。
站点
@Entity(tableName = "sites")
data class Site(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "site_id")
val siteId: Long?,
@ColumnInfo(name = "server_id")
var serverId: Long,
@ColumnInfo(name = "description", defaultValue = "")
val description: String
)
组
@Entity(tableName = "groups")
data class Group(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "group_id")
var groupId: Long?,
@ColumnInfo(name = "server_id") //?
val serverId: Long,
@ColumnInfo(name = "site_id")
val siteId: Long,
@ColumnInfo(name = "description", defaultValue = "")
val description: String
)
Alldao Dao 允许在不同级别插入和提取,特别是使用 @relation
和 JOIN
。
interface AllDao {
@Insert
fun insertServer(server: Server): Long
@Insert
fun insertSite(site: Site): Long
@Insert
fun insertGroup(group: Group): Long
@Query("SELECT * FROM servers")
fun getAllServers(): List<Server>
@Query("SELECT * FROM sites")
fun getAllSites(): List<Site>
@Query("SELECT * FROM groups")
fun getAllGroups(): List<Group>
@Transaction
@Query("SELECT * FROM sites")
fun getAllSitesWithGroups(): List<SiteWithGroup>
@Transaction
@Query("SELECT * FROM servers")
fun getAllServersWithSitesWithGroups(): List<ServerWithSiteWithGroup>
@Transaction
@Query("SELECT * FROM servers INNER JOIN sites ON servers.server_id = sites.server_id INNER JOIN groups on sites.site_id = groups.site_id")
fun getAllServersWithSitesWithGroupsUsingJoin(): List<ServerWithSiteWithGroup>
@Transaction
@Query("Select * from groups " +
"inner join servers on groups.server_id = servers.server_id " +
"where groups.server_id = :serverId " +
"and groups.site_id = :siteId " +
"and groups.group_id = :groupId")
fun getSiteWithGroup(serverId: Long, siteId: Int, groupId: Int): List<ServerWithSiteWithGroup>
}
- 请注意原始查询之前的最后两个
@Query
相似但有细微差别(查看结果)
- 请注意,您查询的只是 returns List 而不是 LiveData
SiteWithGroup 组与其父站点的 POJO 关系(一个站点可以有多个组)
data class SiteWithGroup(
@Embedded
var site: Site,
@Relation(entity = Group::class, entityColumn = "site_id", parentColumn = "site_id")
var groups: List<Group>
)
- 虽然在这种情况下没有必要,但我更喜欢对实体进行编码 (class)
ServerWithSiteWithGroup
data class ServerWithSiteWithGroup(
@Embedded
var server: Server,
@Relation(entity = Site::class, entityColumn = "server_id",parentColumn = "server_id")
var siteWithGroup: List<SiteWithGroup>
)
- 请注意,我使用了与原始名称不同的名称,因为我认为它更能描述底层 POJO。
MyDatabse @Database 抽象 class 将实体和 Dao(s) 联系起来(为了方便,只有一个)
@Database(entities = arrayOf(Server::class,Site::class,Group::class),version = 1)
abstract class MyDatabase: RoomDatabase() {
abstract fun getAllDao(): AllDao
}
MainActivity for demo/bervity/convenience 运行s 在主线程上
class MainActivity : AppCompatActivity() {
val TAG = "MYDBINFO"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val db = Room.databaseBuilder(applicationContext,MyDatabase::class.java,"MyDatabase")
.allowMainThreadQueries()
.build()
val allDao = db.getAllDao()
val s1 = Server(null,1,2,3)
val s2 = Server(null,4,5,6)
allDao.insertServer(s1)
allDao.insertServer(s2)
val site1 = Site(null,1,"Site1 - Server1")
val site2 = Site(null,1,"Site2 - Server1")
val site3 = Site(null,2,"Site3 - Server2")
val site4 = Site(null,2,"Site4 - Server2")
val site5 = Site(null,1,"Site5 - Server 1")
allDao.insertSite(site1)
allDao.insertSite(site2)
allDao.insertSite(site3)
allDao.insertSite(site4)
allDao.insertSite(site5)
val g1 = Group(null,1,1,"Group1 - Site1 (impicitly Server 1)")
val g2 = Group(null,10,1,"Group2!!! - Site1 (impicitly Server 1)") // OOOPS no server with ID 10
val g2_2 = Group(null,1,1,"Group2_2 - Site1 (impicitly Server 1)")
val g3 = Group(null,2,2,"Group3 - Site2 (impicitly Server 1)")
allDao.insertGroup(g1)
allDao.insertGroup(g2)
allDao.insertGroup(g2_2)
allDao.insertGroup(g3)
val servers = allDao.getAllServers()
Log.d(TAG,"Server List")
for (s: Server in servers) {
Log.d(TAG,"\tServerID = " + s.serverId + " CompanyID =" + s.companyId + " AccountID = " + s.accountId + " DeviceID = " + s.deviceId)
}
val sites = allDao.getAllSites()
Log.d(TAG,"Site List")
for (si: Site in sites) {
Log.d(TAG,"\tSiteID = " + si.siteId + " Description = " + si.description + " Server ID = " + si.serverId)
}
val groups = allDao.getAllGroups()
for(g: Group in groups) {
Log.d(TAG,"\tGroup ID = " + g.groupId + " Description = " + g.description + " ServerID = " + g.serverId + " SiteID = " + g.siteId)
}
val sitesWithGroupsList = allDao.getAllSitesWithGroups()
Log.d(TAG,"Site With Groups List")
for(swgl: SiteWithGroup in sitesWithGroupsList) {
Log.d(TAG,"\tSiteID = " + swgl.site.siteId + " ServerID = " + swgl.site.serverId + " Description " + swgl.site.description)
for(grp: Group in swgl.groups) {
Log.d(TAG,"\t\tGroup ID = " + grp.groupId + " SiteID = " + grp.siteId + " Description = " + grp.description + " ServerID = " + grp.serverId)
}
}
Log.d(TAG,"****Servers with Sites with Groups using @Relation")
val swswg = allDao.getAllServersWithSitesWithGroups()
for(s: ServerWithSiteWithGroup in swswg) {
Log.d(TAG,"ServerID is " + s.server.serverId)
Log.d(TAG,"Sites in Server =" + s.siteWithGroup.size)
for(swg: SiteWithGroup in s.siteWithGroup) {
Log.d(TAG,"\tSite is " + swg.site.description)
Log.d(TAG,"\tGroups in Site =" + swg.groups.size)
for (g: Group in swg.groups) {
Log.d(TAG,"\t\tGroup is " + g.description)
}
}
}
Log.d(TAG,"****Servers with Sites with Groups using Joins")
val swswg2 = allDao.getAllServersWithSitesWithGroupsUsingJoin()
for(s: ServerWithSiteWithGroup in swswg2) {
Log.d(TAG,"ServerID is " + s.server.serverId)
Log.d(TAG,"Sites in Server =" + s.siteWithGroup.size)
for(swg: SiteWithGroup in s.siteWithGroup) {
Log.d(TAG,"\tSite is " + swg.site.description)
Log.d(TAG,"\tGroups in Site =" + swg.groups.size)
for (g: Group in swg.groups) {
Log.d(TAG,"\t\tGroup is " + g.description)
}
}
}
// ORIGINAL PROBLEM QUERY
Log.d(TAG,"****Servers With Sites With Groups using joins and where clauses (problem query)")
val swswgsel = allDao.getSiteWithGroup(1,1,1)
for (swswg3: ServerWithSiteWithGroup in swswgsel) {
Log.d(TAG,"ServerID is " + swswg3.server.serverId)
Log.d(TAG,"Sites in Server =" + swswg3.siteWithGroup.size)
for(swg: SiteWithGroup in swswg3.siteWithGroup) {
Log.d(TAG,"\tSite is " + swg.site.description)
Log.d(TAG,"\tGroups in Site =" + swg.groups.size)
for (g: Group in swg.groups) {
Log.d(TAG,"\t\tGroup is " + g.description)
}
}
}
}
}
- 以上依次流过代码
- 日志记录使结果易于监控。
- 设计为 运行 一次(运行多次使用可能会造成一些混乱)
- 为方便起见,使用了 LiveData。
结果运行初始
时的日志
- 您的原始查询在日志末尾
:-
03-28 16:56:24.018 D/MYDBINFO: Server List
03-28 16:56:24.018 D/MYDBINFO: ServerID = 1 DeviceID = 2 AccountID = 1 CompanyID = 3
03-28 16:56:24.018 D/MYDBINFO: ServerID = 2 DeviceID = 5 AccountID = 4 CompanyID = 6
03-28 16:56:24.019 D/MYDBINFO: Site List
03-28 16:56:24.019 D/MYDBINFO: SiteID = 1 Description = Site1 - Server1 ServerID = 1
03-28 16:56:24.019 D/MYDBINFO: SiteID = 2 Description = Site2 - Server1 ServerID = 1
03-28 16:56:24.019 D/MYDBINFO: SiteID = 3 Description = Site3 - Server2 ServerID = 2
03-28 16:56:24.019 D/MYDBINFO: SiteID = 4 Description = Site4 - Server2 ServerID = 2
03-28 16:56:24.019 D/MYDBINFO: SiteID = 5 Description = Site5 - Server 1 ServerID = 1
03-28 16:56:24.021 D/MYDBINFO: Group List
03-28 16:56:24.022 D/MYDBINFO: GroupID = 1 Description = Group1 - Site1 (impicitly Server 1)Parent SiteID = 1 Parent ServerID = 1(May not be correct)
03-28 16:56:24.022 D/MYDBINFO: GroupID = 2 Description = Group2!!! - Site1 (impicitly Server 1)Parent SiteID = 1 Parent ServerID = 10(May not be correct)
03-28 16:56:24.022 D/MYDBINFO: GroupID = 3 Description = Group2_2 - Site1 (impicitly Server 1)Parent SiteID = 1 Parent ServerID = 1(May not be correct)
03-28 16:56:24.022 D/MYDBINFO: GroupID = 4 Description = Group3 - Site2 (impicitly Server 1)Parent SiteID = 2 Parent ServerID = 2(May not be correct)
03-28 16:56:24.024 D/MYDBINFO: Site With Groups List
03-28 16:56:24.024 D/MYDBINFO: SiteID = 1 Description = Site1 - Server1 ServerID = 1
03-28 16:56:24.024 D/MYDBINFO: GroupID = 1 Description = Group1 - Site1 (impicitly Server 1)Parent SiteID = 1 Parent ServerID = 1(May not be correct)
03-28 16:56:24.024 D/MYDBINFO: GroupID = 2 Description = Group2!!! - Site1 (impicitly Server 1)Parent SiteID = 1 Parent ServerID = 10(May not be correct)
03-28 16:56:24.024 D/MYDBINFO: GroupID = 3 Description = Group2_2 - Site1 (impicitly Server 1)Parent SiteID = 1 Parent ServerID = 1(May not be correct)
03-28 16:56:24.024 D/MYDBINFO: SiteID = 2 Description = Site2 - Server1 ServerID = 1
03-28 16:56:24.024 D/MYDBINFO: GroupID = 4 Description = Group3 - Site2 (impicitly Server 1)Parent SiteID = 2 Parent ServerID = 2(May not be correct)
03-28 16:56:24.024 D/MYDBINFO: SiteID = 3 Description = Site3 - Server2 ServerID = 2
03-28 16:56:24.024 D/MYDBINFO: SiteID = 4 Description = Site4 - Server2 ServerID = 2
03-28 16:56:24.025 D/MYDBINFO: SiteID = 5 Description = Site5 - Server 1 ServerID = 1
03-28 16:56:24.025 D/MYDBINFO: ****Servers with Sites with Groups using @Relation
03-28 16:56:24.027 D/MYDBINFO: ServerID = 1 DeviceID = 2 AccountID = 1 CompanyID = 3
03-28 16:56:24.028 D/MYDBINFO: Sites in Server =3
03-28 16:56:24.028 D/MYDBINFO: SiteID = 1 Description = Site1 - Server1 ServerID = 1
03-28 16:56:24.028 D/MYDBINFO: Groups in Site =3
03-28 16:56:24.028 D/MYDBINFO: GroupID = 1 Description = Group1 - Site1 (impicitly Server 1)Parent SiteID = 1 Parent ServerID = 1(May not be correct)
03-28 16:56:24.028 D/MYDBINFO: GroupID = 2 Description = Group2!!! - Site1 (impicitly Server 1)Parent SiteID = 1 Parent ServerID = 10(May not be correct)
03-28 16:56:24.028 D/MYDBINFO: GroupID = 3 Description = Group2_2 - Site1 (impicitly Server 1)Parent SiteID = 1 Parent ServerID = 1(May not be correct)
03-28 16:56:24.028 D/MYDBINFO: SiteID = 2 Description = Site2 - Server1 ServerID = 1
03-28 16:56:24.028 D/MYDBINFO: Groups in Site =1
03-28 16:56:24.028 D/MYDBINFO: GroupID = 4 Description = Group3 - Site2 (impicitly Server 1)Parent SiteID = 2 Parent ServerID = 2(May not be correct)
03-28 16:56:24.028 D/MYDBINFO: SiteID = 5 Description = Site5 - Server 1 ServerID = 1
03-28 16:56:24.028 D/MYDBINFO: Groups in Site =0
03-28 16:56:24.028 D/MYDBINFO: ServerID = 2 DeviceID = 5 AccountID = 4 CompanyID = 6
03-28 16:56:24.028 D/MYDBINFO: Sites in Server =2
03-28 16:56:24.028 D/MYDBINFO: SiteID = 3 Description = Site3 - Server2 ServerID = 2
03-28 16:56:24.028 D/MYDBINFO: Groups in Site =0
03-28 16:56:24.028 D/MYDBINFO: SiteID = 4 Description = Site4 - Server2 ServerID = 2
03-28 16:56:24.028 D/MYDBINFO: Groups in Site =0
03-28 16:56:24.028 D/MYDBINFO: ****Servers with Sites with Groups using Joins
03-28 16:56:24.029 D/MYDBINFO: ServerID = 1 DeviceID = 2 AccountID = 1 CompanyID = 3
03-28 16:56:24.029 D/MYDBINFO: Sites in Server =3
03-28 16:56:24.029 D/MYDBINFO: SiteID = 1 Description = Site1 - Server1 ServerID = 1
03-28 16:56:24.029 D/MYDBINFO: Groups in Site =3
03-28 16:56:24.029 D/MYDBINFO: GroupID = 1 Description = Group1 - Site1 (impicitly Server 1)Parent SiteID = 1 Parent ServerID = 1(May not be correct)
03-28 16:56:24.029 D/MYDBINFO: GroupID = 2 Description = Group2!!! - Site1 (impicitly Server 1)Parent SiteID = 1 Parent ServerID = 10(May not be correct)
03-28 16:56:24.029 D/MYDBINFO: GroupID = 3 Description = Group2_2 - Site1 (impicitly Server 1)Parent SiteID = 1 Parent ServerID = 1(May not be correct)
03-28 16:56:24.029 D/MYDBINFO: SiteID = 2 Description = Site2 - Server1 ServerID = 1
03-28 16:56:24.029 D/MYDBINFO: Groups in Site =1
03-28 16:56:24.029 D/MYDBINFO: GroupID = 4 Description = Group3 - Site2 (impicitly Server 1)Parent SiteID = 2 Parent ServerID = 2(May not be correct)
03-28 16:56:24.029 D/MYDBINFO: SiteID = 5 Description = Site5 - Server 1 ServerID = 1
03-28 16:56:24.029 D/MYDBINFO: Groups in Site =0
03-28 16:56:24.029 D/MYDBINFO: ServerID = 10 DeviceID = 2 AccountID = 1 CompanyID = 3
03-28 16:56:24.029 D/MYDBINFO: Sites in Server =0
03-28 16:56:24.029 D/MYDBINFO: ServerID = 1 DeviceID = 2 AccountID = 1 CompanyID = 3
03-28 16:56:24.029 D/MYDBINFO: Sites in Server =3
03-28 16:56:24.030 D/MYDBINFO: SiteID = 1 Description = Site1 - Server1 ServerID = 1
03-28 16:56:24.030 D/MYDBINFO: Groups in Site =3
03-28 16:56:24.030 D/MYDBINFO: GroupID = 1 Description = Group1 - Site1 (impicitly Server 1)Parent SiteID = 1 Parent ServerID = 1(May not be correct)
03-28 16:56:24.030 D/MYDBINFO: GroupID = 2 Description = Group2!!! - Site1 (impicitly Server 1)Parent SiteID = 1 Parent ServerID = 10(May not be correct)
03-28 16:56:24.030 D/MYDBINFO: GroupID = 3 Description = Group2_2 - Site1 (impicitly Server 1)Parent SiteID = 1 Parent ServerID = 1(May not be correct)
03-28 16:56:24.030 D/MYDBINFO: SiteID = 2 Description = Site2 - Server1 ServerID = 1
03-28 16:56:24.030 D/MYDBINFO: Groups in Site =1
03-28 16:56:24.030 D/MYDBINFO: GroupID = 4 Description = Group3 - Site2 (impicitly Server 1)Parent SiteID = 2 Parent ServerID = 2(May not be correct)
03-28 16:56:24.030 D/MYDBINFO: SiteID = 5 Description = Site5 - Server 1 ServerID = 1
03-28 16:56:24.030 D/MYDBINFO: Groups in Site =0
03-28 16:56:24.030 D/MYDBINFO: ServerID = 2 DeviceID = 2 AccountID = 1 CompanyID = 3
03-28 16:56:24.030 D/MYDBINFO: Sites in Server =2
03-28 16:56:24.030 D/MYDBINFO: SiteID = 3 Description = Site3 - Server2 ServerID = 2
03-28 16:56:24.030 D/MYDBINFO: Groups in Site =0
03-28 16:56:24.030 D/MYDBINFO: SiteID = 4 Description = Site4 - Server2 ServerID = 2
03-28 16:56:24.030 D/MYDBINFO: Groups in Site =0
03-28 16:56:24.030 D/MYDBINFO: ****Servers With Sites With Groups using joins and where claues (problem query)
03-28 16:56:24.031 D/MYDBINFO: ServerID = 1 DeviceID = 2 AccountID = 1 CompanyID = 3
03-28 16:56:24.031 D/MYDBINFO: Sites in Server =3
03-28 16:56:24.031 D/MYDBINFO: SiteID = 1 Description = Site1 - Server1 ServerID = 1
03-28 16:56:24.031 D/MYDBINFO: Groups in Site = 3
03-28 16:56:24.031 D/MYDBINFO: GroupID = 1 Description = Group1 - Site1 (impicitly Server 1)Parent SiteID = 1 Parent ServerID = 1(May not be correct)
03-28 16:56:24.031 D/MYDBINFO: GroupID = 2 Description = Group2!!! - Site1 (impicitly Server 1)Parent SiteID = 1 Parent ServerID = 10(May not be correct)
03-28 16:56:24.031 D/MYDBINFO: GroupID = 3 Description = Group2_2 - Site1 (impicitly Server 1)Parent SiteID = 1 Parent ServerID = 1(May not be correct)
03-28 16:56:24.031 D/MYDBINFO: SiteID = 2 Description = Site2 - Server1 ServerID = 1
03-28 16:56:24.032 D/MYDBINFO: Groups in Site = 1
03-28 16:56:24.032 D/MYDBINFO: GroupID = 4 Description = Group3 - Site2 (impicitly Server 1)Parent SiteID = 2 Parent ServerID = 2(May not be correct)
03-28 16:56:24.032 D/MYDBINFO: SiteID = 5 Description = Site5 - Server 1 ServerID = 1
03-28 16:56:24.032 D/MYDBINFO: Groups in Site = 0
额外
您可能希望考虑以下使用看似正确关系的内容:-
@Transaction
@Query("SELECT * FROM servers " +
"JOIN sites ON sites.server_id = servers.server_id " +
"JOIN groups ON groups.site_id = sites.site_id " +
"WHERE servers.server_id = :serverId AND sites.site_id = :siteId AND groups.group_id = :groupId")
fun getSuggested(serverId: Long, siteId: Long, groupId: Long): List<ServerWithSiteWithGroup>
对于相同的测试用例,这实际上实现了相同的结果:-
03-28 16:56:24.032 D/MYDBINFO: ????Servers With Sites With Groups and WHERE clause (suggested)
03-28 16:56:24.033 D/MYDBINFO: ServerID = 1 DeviceID = 2 AccountID = 1 CompanyID = 3
03-28 16:56:24.033 D/MYDBINFO: Sites in Server = 3
03-28 16:56:24.033 D/MYDBINFO: SiteID = 1 Description = Site1 - Server1 ServerID = 1
03-28 16:56:24.033 D/MYDBINFO: Groups in Site = 3
03-28 16:56:24.033 D/MYDBINFO: GroupID = 1 Description = Group1 - Site1 (impicitly Server 1)Parent SiteID = 1 Parent ServerID = 1(May not be correct)
03-28 16:56:24.033 D/MYDBINFO: GroupID = 2 Description = Group2!!! - Site1 (impicitly Server 1)Parent SiteID = 1 Parent ServerID = 10(May not be correct)
03-28 16:56:24.033 D/MYDBINFO: GroupID = 3 Description = Group2_2 - Site1 (impicitly Server 1)Parent SiteID = 1 Parent ServerID = 1(May not be correct)
03-28 16:56:24.033 D/MYDBINFO: SiteID = 2 Description = Site2 - Server1 ServerID = 1
03-28 16:56:24.033 D/MYDBINFO: Groups in Site = 1
03-28 16:56:24.033 D/MYDBINFO: GroupID = 4 Description = Group3 - Site2 (impicitly Server 1)Parent SiteID = 2 Parent ServerID = 2(May not be correct)
03-28 16:56:24.033 D/MYDBINFO: SiteID = 5 Description = Site5 - Server 1 ServerID = 1
03-28 16:56:24.033 D/MYDBINFO: Groups in Site = 0
更多
可能是您不期望结果,而是在指定所有三个参数时期望一个 Server/Site/Group。如果是这样,那么我认为使用 @Relation
不是可行的方法。相反,没有关系的 POJO 才是正确的选择。
在后面的查询中考虑 SQL 例如:-
SELECT *,sites.description AS site_description, groups.description AS group_description FROM groups
INNER JOIN sites ON sites.site_id = groups.site_id
INNER JOIN servers ON servers.server_id = sites.server_id
WHERE servers.server_id = 1 AND sites.site_id = 1 AND groups.group_id = 1;
有了上面的数据(注意sites.description AS site_description, groups.description AS group_description
是disambiguate/distinguish 来自不同表的相同列名)。
您可能会期望(当参数为 1,1,1 时):-
如上面的日志所示,这不是 Room 提供的内容。
但是考虑 POJO :-
class AltServerSiteGroup {
var server_id: Long = 0
var device_id: Long = 0
var account_id: Long = 0
var company_id: Long = 0
var site_id: Long = -1
var site_description: String = ""
var group_id: Long = -1
var group_description: String = ""
}
- 注意我改为使用 Long 而不是 Int(在
Server
中也是如此)。
然后考虑道:-
@Transaction
@Query("SELECT *, sites.description AS site_description, groups.description AS group_description FROM groups " +
"INNER JOIN sites ON sites.site_id = groups.site_id " +
"INNER JOIN servers ON servers.server_id = sites.server_id " +
"WHERE servers.server_id = :serverId AND sites.site_id = :siteId AND groups.group_id = :groupId")
fun getAlt(serverId: Long, siteId: Long, groupId: Long): List<AltServerSiteGroup>
- 如果只有 1 个值被 returned 是可能的(如果 ID 是主键,情况就是这样),则可以使用
AltServerSiteGroup
而不是 List<AltServerSiteGroup>
。
因此,将以下内容添加到 MainActivity 中:-
Log.d(TAG, "Alternative Perhaps what is wanted")
val alt = allDao.getAlt(1,1,1)
for(s: AltServerSiteGroup in alt) {
logserver(Server(s.server_id,s.account_id,s.device_id,s.company_id))
logsite(Site(s.site_id,s.server_id,s.site_description))
loggroup(Group(s.group_id,s.server_id,s.site_id,s.group_description))
}
- 添加了用于记录实体的函数,因此记录了 logserver(Server(....)) 等
那么该部分的结果将是:-
03-28 19:10:41.930 D/MYDBINFO: Alternative Perhaps what is wanted
03-28 19:10:41.931 D/MYDBINFO: ServerID = 1 DeviceID = 2 AccountID = 1 CompanyID = 3
03-28 19:10:41.931 D/MYDBINFO: SiteID = 1 Description = Site1 - Server1 ServerID = 1
03-28 19:10:41.931 D/MYDBINFO: GroupID = 1 Description = Group1 - Site1 (impicitly Server 1)Parent SiteID = 1 Parent ServerID = 1(May not be correct)
即符合选择条件的单个 Server/Site/group。
您可以将功能添加到 AltServerSiteGroup 以 return 提取的 Server/Site/Group 对象,但请注意,这些将与 complete/full 对象不同,因为它们只有一个服务器站点-组例如:-
class AltServerSiteGroup {
var server_id: Long = 0
var device_id: Long = 0
var account_id: Long = 0
var company_id: Long = 0
var site_id: Long = -1
var site_description: String = ""
var group_id: Long = -1
var group_description: String = ""
fun getServer(): Server {
return Server(server_id,account_id,device_id,company_id)
}
fun getSite(): Site {
return Site(site_id,server_id,site_description)
}
fun getGroup(): Group {
return Group(group_id,server_id,site_id,group_description)
}
}
说明
简而言之,Room 将根据 @Relation
构建 complete 对象,从而添加额外的 unwanted[=170] =] 站点和组。
如果您查看 Java(生成)中的 Dao 代码(使用项目 window 中的 Android 视图),请注意文件名后缀为_Impl (所以对于AllDao
,如上所用,在生成的java中是AllDao_Impl
),你会看到房间是做什么的,为 getAlt
构建的代码比 getSiteWithGroup
.
的代码短很多
我的应用程序中有一个数据库,它有 3 个表服务器、站点、组
@Entity(tableName = "servers")
data class Server(
@ColumnInfo(name = "server_id")
var serverId: Long,
@ColumnInfo(name = "account_id")
var accountId: Int,
@ColumnInfo(name = "device_id")
var deviceId: Int,
@ColumnInfo(name = "company_id")
var companyId: Int
.......
@Entity(tableName = "sites")
data class Site(
@ColumnInfo(name = "server_id")
var serverId: Long,
@ColumnInfo(name = "site_id")
val siteId: Int,
@ColumnInfo(name = "description", defaultValue = "")
val description: String
)
@Entity(tableName = "groups")
data class Group(
@ColumnInfo(name = "server_id")
val serverId: Long,
@ColumnInfo(name = "group_id")
var groupId: Int,
@ColumnInfo(name = "site_id")
val siteId: Int,
@ColumnInfo(name = "description", defaultValue = "")
val description: String
......
因此我们可以看到,对于每台服务器,我们都有站点,并且每个站点都有多个组。 现在我制作了一个名为 ServerSiteWithGroup 的 POJO,其中包含一个服务器和另一个 POJO SiteWithGroup
data class ServerSiteWithGroup(
@Embedded
val server: Server,
@Relation(parentColumn = "server_id", entityColumn = "server_id")
val siteWithGroup: SiteWithGroup
)
data class SiteWithGroup(
@Embedded
val group: Group,
@Relation(parentColumn = "site_id", entityColumn = "site_id")
val site: Site
)
鉴于我想对房间数据库进行一次查询并在给定 serverId, siteId, groupId
我已经试过了,但是没用
@Transaction
@Query("Select * from groups
inner join servers on groups.server_id = servers.server_id
where groups.server_id = :serverId
and groups.site_id = :siteId
and groups.group_id = :groupId")
fun getSiteWithGroup(serverId: Long, siteId: Int, groupId: Int): LiveData<ServerSiteWithGroup>
我该如何解决这个问题?
首先,您似乎没有使用 @PrimaryKey 注释定义任何主键,这会导致编译错误。
其次,@Query 不应该 return LiveData<ServerSiteWithGroup>
但应该 return 一个 LiveData 数组,它们本身是(我相信)ServerSiteWithGroup 的数组,所以我认为应该 return =28=].
- 也许先试试这个 但是考虑一下 Even More 部分已经添加到答案结束。 .
How can i solve that problem?
- 您不mention/specify实际问题是什么。但是,以下是基于您提供的信息的解决方案。 (但为了方便没有使用
LiveData
)
在您拥有 ServerId 的群组实体中,这是不必要的,因为作为群组父级的站点将服务器作为其父级。这不是错误,但没有必要。
虽然理论上不需要,但 id 可以是 Long,因此我总是建议在关系中使用 Long 而不是 Int。
例子 这是一个基于您的代码的工作示例。
服务器
@Entity(tableName = "servers")
data class Server(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "server_id")
var serverId: Long?,
@ColumnInfo(name = "account_id")
var accountId: Int,
@ColumnInfo(name = "device_id")
var deviceId: Int,
@ColumnInfo(name = "company_id")
var companyId: Int
)
Primarykey
已定义。autogenerate
和Long?
允许生成 id。
站点
@Entity(tableName = "sites")
data class Site(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "site_id")
val siteId: Long?,
@ColumnInfo(name = "server_id")
var serverId: Long,
@ColumnInfo(name = "description", defaultValue = "")
val description: String
)
组
@Entity(tableName = "groups")
data class Group(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "group_id")
var groupId: Long?,
@ColumnInfo(name = "server_id") //?
val serverId: Long,
@ColumnInfo(name = "site_id")
val siteId: Long,
@ColumnInfo(name = "description", defaultValue = "")
val description: String
)
Alldao Dao 允许在不同级别插入和提取,特别是使用 @relation
和 JOIN
。
interface AllDao {
@Insert
fun insertServer(server: Server): Long
@Insert
fun insertSite(site: Site): Long
@Insert
fun insertGroup(group: Group): Long
@Query("SELECT * FROM servers")
fun getAllServers(): List<Server>
@Query("SELECT * FROM sites")
fun getAllSites(): List<Site>
@Query("SELECT * FROM groups")
fun getAllGroups(): List<Group>
@Transaction
@Query("SELECT * FROM sites")
fun getAllSitesWithGroups(): List<SiteWithGroup>
@Transaction
@Query("SELECT * FROM servers")
fun getAllServersWithSitesWithGroups(): List<ServerWithSiteWithGroup>
@Transaction
@Query("SELECT * FROM servers INNER JOIN sites ON servers.server_id = sites.server_id INNER JOIN groups on sites.site_id = groups.site_id")
fun getAllServersWithSitesWithGroupsUsingJoin(): List<ServerWithSiteWithGroup>
@Transaction
@Query("Select * from groups " +
"inner join servers on groups.server_id = servers.server_id " +
"where groups.server_id = :serverId " +
"and groups.site_id = :siteId " +
"and groups.group_id = :groupId")
fun getSiteWithGroup(serverId: Long, siteId: Int, groupId: Int): List<ServerWithSiteWithGroup>
}
- 请注意原始查询之前的最后两个
@Query
相似但有细微差别(查看结果) - 请注意,您查询的只是 returns List 而不是 LiveData
SiteWithGroup 组与其父站点的 POJO 关系(一个站点可以有多个组)
data class SiteWithGroup(
@Embedded
var site: Site,
@Relation(entity = Group::class, entityColumn = "site_id", parentColumn = "site_id")
var groups: List<Group>
)
- 虽然在这种情况下没有必要,但我更喜欢对实体进行编码 (class)
ServerWithSiteWithGroup
data class ServerWithSiteWithGroup(
@Embedded
var server: Server,
@Relation(entity = Site::class, entityColumn = "server_id",parentColumn = "server_id")
var siteWithGroup: List<SiteWithGroup>
)
- 请注意,我使用了与原始名称不同的名称,因为我认为它更能描述底层 POJO。
MyDatabse @Database 抽象 class 将实体和 Dao(s) 联系起来(为了方便,只有一个)
@Database(entities = arrayOf(Server::class,Site::class,Group::class),version = 1)
abstract class MyDatabase: RoomDatabase() {
abstract fun getAllDao(): AllDao
}
MainActivity for demo/bervity/convenience 运行s 在主线程上
class MainActivity : AppCompatActivity() {
val TAG = "MYDBINFO"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val db = Room.databaseBuilder(applicationContext,MyDatabase::class.java,"MyDatabase")
.allowMainThreadQueries()
.build()
val allDao = db.getAllDao()
val s1 = Server(null,1,2,3)
val s2 = Server(null,4,5,6)
allDao.insertServer(s1)
allDao.insertServer(s2)
val site1 = Site(null,1,"Site1 - Server1")
val site2 = Site(null,1,"Site2 - Server1")
val site3 = Site(null,2,"Site3 - Server2")
val site4 = Site(null,2,"Site4 - Server2")
val site5 = Site(null,1,"Site5 - Server 1")
allDao.insertSite(site1)
allDao.insertSite(site2)
allDao.insertSite(site3)
allDao.insertSite(site4)
allDao.insertSite(site5)
val g1 = Group(null,1,1,"Group1 - Site1 (impicitly Server 1)")
val g2 = Group(null,10,1,"Group2!!! - Site1 (impicitly Server 1)") // OOOPS no server with ID 10
val g2_2 = Group(null,1,1,"Group2_2 - Site1 (impicitly Server 1)")
val g3 = Group(null,2,2,"Group3 - Site2 (impicitly Server 1)")
allDao.insertGroup(g1)
allDao.insertGroup(g2)
allDao.insertGroup(g2_2)
allDao.insertGroup(g3)
val servers = allDao.getAllServers()
Log.d(TAG,"Server List")
for (s: Server in servers) {
Log.d(TAG,"\tServerID = " + s.serverId + " CompanyID =" + s.companyId + " AccountID = " + s.accountId + " DeviceID = " + s.deviceId)
}
val sites = allDao.getAllSites()
Log.d(TAG,"Site List")
for (si: Site in sites) {
Log.d(TAG,"\tSiteID = " + si.siteId + " Description = " + si.description + " Server ID = " + si.serverId)
}
val groups = allDao.getAllGroups()
for(g: Group in groups) {
Log.d(TAG,"\tGroup ID = " + g.groupId + " Description = " + g.description + " ServerID = " + g.serverId + " SiteID = " + g.siteId)
}
val sitesWithGroupsList = allDao.getAllSitesWithGroups()
Log.d(TAG,"Site With Groups List")
for(swgl: SiteWithGroup in sitesWithGroupsList) {
Log.d(TAG,"\tSiteID = " + swgl.site.siteId + " ServerID = " + swgl.site.serverId + " Description " + swgl.site.description)
for(grp: Group in swgl.groups) {
Log.d(TAG,"\t\tGroup ID = " + grp.groupId + " SiteID = " + grp.siteId + " Description = " + grp.description + " ServerID = " + grp.serverId)
}
}
Log.d(TAG,"****Servers with Sites with Groups using @Relation")
val swswg = allDao.getAllServersWithSitesWithGroups()
for(s: ServerWithSiteWithGroup in swswg) {
Log.d(TAG,"ServerID is " + s.server.serverId)
Log.d(TAG,"Sites in Server =" + s.siteWithGroup.size)
for(swg: SiteWithGroup in s.siteWithGroup) {
Log.d(TAG,"\tSite is " + swg.site.description)
Log.d(TAG,"\tGroups in Site =" + swg.groups.size)
for (g: Group in swg.groups) {
Log.d(TAG,"\t\tGroup is " + g.description)
}
}
}
Log.d(TAG,"****Servers with Sites with Groups using Joins")
val swswg2 = allDao.getAllServersWithSitesWithGroupsUsingJoin()
for(s: ServerWithSiteWithGroup in swswg2) {
Log.d(TAG,"ServerID is " + s.server.serverId)
Log.d(TAG,"Sites in Server =" + s.siteWithGroup.size)
for(swg: SiteWithGroup in s.siteWithGroup) {
Log.d(TAG,"\tSite is " + swg.site.description)
Log.d(TAG,"\tGroups in Site =" + swg.groups.size)
for (g: Group in swg.groups) {
Log.d(TAG,"\t\tGroup is " + g.description)
}
}
}
// ORIGINAL PROBLEM QUERY
Log.d(TAG,"****Servers With Sites With Groups using joins and where clauses (problem query)")
val swswgsel = allDao.getSiteWithGroup(1,1,1)
for (swswg3: ServerWithSiteWithGroup in swswgsel) {
Log.d(TAG,"ServerID is " + swswg3.server.serverId)
Log.d(TAG,"Sites in Server =" + swswg3.siteWithGroup.size)
for(swg: SiteWithGroup in swswg3.siteWithGroup) {
Log.d(TAG,"\tSite is " + swg.site.description)
Log.d(TAG,"\tGroups in Site =" + swg.groups.size)
for (g: Group in swg.groups) {
Log.d(TAG,"\t\tGroup is " + g.description)
}
}
}
}
}
- 以上依次流过代码
- 日志记录使结果易于监控。
- 设计为 运行 一次(运行多次使用可能会造成一些混乱)
- 为方便起见,使用了 LiveData。
结果运行初始
时的日志- 您的原始查询在日志末尾
:-
03-28 16:56:24.018 D/MYDBINFO: Server List
03-28 16:56:24.018 D/MYDBINFO: ServerID = 1 DeviceID = 2 AccountID = 1 CompanyID = 3
03-28 16:56:24.018 D/MYDBINFO: ServerID = 2 DeviceID = 5 AccountID = 4 CompanyID = 6
03-28 16:56:24.019 D/MYDBINFO: Site List
03-28 16:56:24.019 D/MYDBINFO: SiteID = 1 Description = Site1 - Server1 ServerID = 1
03-28 16:56:24.019 D/MYDBINFO: SiteID = 2 Description = Site2 - Server1 ServerID = 1
03-28 16:56:24.019 D/MYDBINFO: SiteID = 3 Description = Site3 - Server2 ServerID = 2
03-28 16:56:24.019 D/MYDBINFO: SiteID = 4 Description = Site4 - Server2 ServerID = 2
03-28 16:56:24.019 D/MYDBINFO: SiteID = 5 Description = Site5 - Server 1 ServerID = 1
03-28 16:56:24.021 D/MYDBINFO: Group List
03-28 16:56:24.022 D/MYDBINFO: GroupID = 1 Description = Group1 - Site1 (impicitly Server 1)Parent SiteID = 1 Parent ServerID = 1(May not be correct)
03-28 16:56:24.022 D/MYDBINFO: GroupID = 2 Description = Group2!!! - Site1 (impicitly Server 1)Parent SiteID = 1 Parent ServerID = 10(May not be correct)
03-28 16:56:24.022 D/MYDBINFO: GroupID = 3 Description = Group2_2 - Site1 (impicitly Server 1)Parent SiteID = 1 Parent ServerID = 1(May not be correct)
03-28 16:56:24.022 D/MYDBINFO: GroupID = 4 Description = Group3 - Site2 (impicitly Server 1)Parent SiteID = 2 Parent ServerID = 2(May not be correct)
03-28 16:56:24.024 D/MYDBINFO: Site With Groups List
03-28 16:56:24.024 D/MYDBINFO: SiteID = 1 Description = Site1 - Server1 ServerID = 1
03-28 16:56:24.024 D/MYDBINFO: GroupID = 1 Description = Group1 - Site1 (impicitly Server 1)Parent SiteID = 1 Parent ServerID = 1(May not be correct)
03-28 16:56:24.024 D/MYDBINFO: GroupID = 2 Description = Group2!!! - Site1 (impicitly Server 1)Parent SiteID = 1 Parent ServerID = 10(May not be correct)
03-28 16:56:24.024 D/MYDBINFO: GroupID = 3 Description = Group2_2 - Site1 (impicitly Server 1)Parent SiteID = 1 Parent ServerID = 1(May not be correct)
03-28 16:56:24.024 D/MYDBINFO: SiteID = 2 Description = Site2 - Server1 ServerID = 1
03-28 16:56:24.024 D/MYDBINFO: GroupID = 4 Description = Group3 - Site2 (impicitly Server 1)Parent SiteID = 2 Parent ServerID = 2(May not be correct)
03-28 16:56:24.024 D/MYDBINFO: SiteID = 3 Description = Site3 - Server2 ServerID = 2
03-28 16:56:24.024 D/MYDBINFO: SiteID = 4 Description = Site4 - Server2 ServerID = 2
03-28 16:56:24.025 D/MYDBINFO: SiteID = 5 Description = Site5 - Server 1 ServerID = 1
03-28 16:56:24.025 D/MYDBINFO: ****Servers with Sites with Groups using @Relation
03-28 16:56:24.027 D/MYDBINFO: ServerID = 1 DeviceID = 2 AccountID = 1 CompanyID = 3
03-28 16:56:24.028 D/MYDBINFO: Sites in Server =3
03-28 16:56:24.028 D/MYDBINFO: SiteID = 1 Description = Site1 - Server1 ServerID = 1
03-28 16:56:24.028 D/MYDBINFO: Groups in Site =3
03-28 16:56:24.028 D/MYDBINFO: GroupID = 1 Description = Group1 - Site1 (impicitly Server 1)Parent SiteID = 1 Parent ServerID = 1(May not be correct)
03-28 16:56:24.028 D/MYDBINFO: GroupID = 2 Description = Group2!!! - Site1 (impicitly Server 1)Parent SiteID = 1 Parent ServerID = 10(May not be correct)
03-28 16:56:24.028 D/MYDBINFO: GroupID = 3 Description = Group2_2 - Site1 (impicitly Server 1)Parent SiteID = 1 Parent ServerID = 1(May not be correct)
03-28 16:56:24.028 D/MYDBINFO: SiteID = 2 Description = Site2 - Server1 ServerID = 1
03-28 16:56:24.028 D/MYDBINFO: Groups in Site =1
03-28 16:56:24.028 D/MYDBINFO: GroupID = 4 Description = Group3 - Site2 (impicitly Server 1)Parent SiteID = 2 Parent ServerID = 2(May not be correct)
03-28 16:56:24.028 D/MYDBINFO: SiteID = 5 Description = Site5 - Server 1 ServerID = 1
03-28 16:56:24.028 D/MYDBINFO: Groups in Site =0
03-28 16:56:24.028 D/MYDBINFO: ServerID = 2 DeviceID = 5 AccountID = 4 CompanyID = 6
03-28 16:56:24.028 D/MYDBINFO: Sites in Server =2
03-28 16:56:24.028 D/MYDBINFO: SiteID = 3 Description = Site3 - Server2 ServerID = 2
03-28 16:56:24.028 D/MYDBINFO: Groups in Site =0
03-28 16:56:24.028 D/MYDBINFO: SiteID = 4 Description = Site4 - Server2 ServerID = 2
03-28 16:56:24.028 D/MYDBINFO: Groups in Site =0
03-28 16:56:24.028 D/MYDBINFO: ****Servers with Sites with Groups using Joins
03-28 16:56:24.029 D/MYDBINFO: ServerID = 1 DeviceID = 2 AccountID = 1 CompanyID = 3
03-28 16:56:24.029 D/MYDBINFO: Sites in Server =3
03-28 16:56:24.029 D/MYDBINFO: SiteID = 1 Description = Site1 - Server1 ServerID = 1
03-28 16:56:24.029 D/MYDBINFO: Groups in Site =3
03-28 16:56:24.029 D/MYDBINFO: GroupID = 1 Description = Group1 - Site1 (impicitly Server 1)Parent SiteID = 1 Parent ServerID = 1(May not be correct)
03-28 16:56:24.029 D/MYDBINFO: GroupID = 2 Description = Group2!!! - Site1 (impicitly Server 1)Parent SiteID = 1 Parent ServerID = 10(May not be correct)
03-28 16:56:24.029 D/MYDBINFO: GroupID = 3 Description = Group2_2 - Site1 (impicitly Server 1)Parent SiteID = 1 Parent ServerID = 1(May not be correct)
03-28 16:56:24.029 D/MYDBINFO: SiteID = 2 Description = Site2 - Server1 ServerID = 1
03-28 16:56:24.029 D/MYDBINFO: Groups in Site =1
03-28 16:56:24.029 D/MYDBINFO: GroupID = 4 Description = Group3 - Site2 (impicitly Server 1)Parent SiteID = 2 Parent ServerID = 2(May not be correct)
03-28 16:56:24.029 D/MYDBINFO: SiteID = 5 Description = Site5 - Server 1 ServerID = 1
03-28 16:56:24.029 D/MYDBINFO: Groups in Site =0
03-28 16:56:24.029 D/MYDBINFO: ServerID = 10 DeviceID = 2 AccountID = 1 CompanyID = 3
03-28 16:56:24.029 D/MYDBINFO: Sites in Server =0
03-28 16:56:24.029 D/MYDBINFO: ServerID = 1 DeviceID = 2 AccountID = 1 CompanyID = 3
03-28 16:56:24.029 D/MYDBINFO: Sites in Server =3
03-28 16:56:24.030 D/MYDBINFO: SiteID = 1 Description = Site1 - Server1 ServerID = 1
03-28 16:56:24.030 D/MYDBINFO: Groups in Site =3
03-28 16:56:24.030 D/MYDBINFO: GroupID = 1 Description = Group1 - Site1 (impicitly Server 1)Parent SiteID = 1 Parent ServerID = 1(May not be correct)
03-28 16:56:24.030 D/MYDBINFO: GroupID = 2 Description = Group2!!! - Site1 (impicitly Server 1)Parent SiteID = 1 Parent ServerID = 10(May not be correct)
03-28 16:56:24.030 D/MYDBINFO: GroupID = 3 Description = Group2_2 - Site1 (impicitly Server 1)Parent SiteID = 1 Parent ServerID = 1(May not be correct)
03-28 16:56:24.030 D/MYDBINFO: SiteID = 2 Description = Site2 - Server1 ServerID = 1
03-28 16:56:24.030 D/MYDBINFO: Groups in Site =1
03-28 16:56:24.030 D/MYDBINFO: GroupID = 4 Description = Group3 - Site2 (impicitly Server 1)Parent SiteID = 2 Parent ServerID = 2(May not be correct)
03-28 16:56:24.030 D/MYDBINFO: SiteID = 5 Description = Site5 - Server 1 ServerID = 1
03-28 16:56:24.030 D/MYDBINFO: Groups in Site =0
03-28 16:56:24.030 D/MYDBINFO: ServerID = 2 DeviceID = 2 AccountID = 1 CompanyID = 3
03-28 16:56:24.030 D/MYDBINFO: Sites in Server =2
03-28 16:56:24.030 D/MYDBINFO: SiteID = 3 Description = Site3 - Server2 ServerID = 2
03-28 16:56:24.030 D/MYDBINFO: Groups in Site =0
03-28 16:56:24.030 D/MYDBINFO: SiteID = 4 Description = Site4 - Server2 ServerID = 2
03-28 16:56:24.030 D/MYDBINFO: Groups in Site =0
03-28 16:56:24.030 D/MYDBINFO: ****Servers With Sites With Groups using joins and where claues (problem query)
03-28 16:56:24.031 D/MYDBINFO: ServerID = 1 DeviceID = 2 AccountID = 1 CompanyID = 3
03-28 16:56:24.031 D/MYDBINFO: Sites in Server =3
03-28 16:56:24.031 D/MYDBINFO: SiteID = 1 Description = Site1 - Server1 ServerID = 1
03-28 16:56:24.031 D/MYDBINFO: Groups in Site = 3
03-28 16:56:24.031 D/MYDBINFO: GroupID = 1 Description = Group1 - Site1 (impicitly Server 1)Parent SiteID = 1 Parent ServerID = 1(May not be correct)
03-28 16:56:24.031 D/MYDBINFO: GroupID = 2 Description = Group2!!! - Site1 (impicitly Server 1)Parent SiteID = 1 Parent ServerID = 10(May not be correct)
03-28 16:56:24.031 D/MYDBINFO: GroupID = 3 Description = Group2_2 - Site1 (impicitly Server 1)Parent SiteID = 1 Parent ServerID = 1(May not be correct)
03-28 16:56:24.031 D/MYDBINFO: SiteID = 2 Description = Site2 - Server1 ServerID = 1
03-28 16:56:24.032 D/MYDBINFO: Groups in Site = 1
03-28 16:56:24.032 D/MYDBINFO: GroupID = 4 Description = Group3 - Site2 (impicitly Server 1)Parent SiteID = 2 Parent ServerID = 2(May not be correct)
03-28 16:56:24.032 D/MYDBINFO: SiteID = 5 Description = Site5 - Server 1 ServerID = 1
03-28 16:56:24.032 D/MYDBINFO: Groups in Site = 0
额外 您可能希望考虑以下使用看似正确关系的内容:-
@Transaction
@Query("SELECT * FROM servers " +
"JOIN sites ON sites.server_id = servers.server_id " +
"JOIN groups ON groups.site_id = sites.site_id " +
"WHERE servers.server_id = :serverId AND sites.site_id = :siteId AND groups.group_id = :groupId")
fun getSuggested(serverId: Long, siteId: Long, groupId: Long): List<ServerWithSiteWithGroup>
对于相同的测试用例,这实际上实现了相同的结果:-
03-28 16:56:24.032 D/MYDBINFO: ????Servers With Sites With Groups and WHERE clause (suggested)
03-28 16:56:24.033 D/MYDBINFO: ServerID = 1 DeviceID = 2 AccountID = 1 CompanyID = 3
03-28 16:56:24.033 D/MYDBINFO: Sites in Server = 3
03-28 16:56:24.033 D/MYDBINFO: SiteID = 1 Description = Site1 - Server1 ServerID = 1
03-28 16:56:24.033 D/MYDBINFO: Groups in Site = 3
03-28 16:56:24.033 D/MYDBINFO: GroupID = 1 Description = Group1 - Site1 (impicitly Server 1)Parent SiteID = 1 Parent ServerID = 1(May not be correct)
03-28 16:56:24.033 D/MYDBINFO: GroupID = 2 Description = Group2!!! - Site1 (impicitly Server 1)Parent SiteID = 1 Parent ServerID = 10(May not be correct)
03-28 16:56:24.033 D/MYDBINFO: GroupID = 3 Description = Group2_2 - Site1 (impicitly Server 1)Parent SiteID = 1 Parent ServerID = 1(May not be correct)
03-28 16:56:24.033 D/MYDBINFO: SiteID = 2 Description = Site2 - Server1 ServerID = 1
03-28 16:56:24.033 D/MYDBINFO: Groups in Site = 1
03-28 16:56:24.033 D/MYDBINFO: GroupID = 4 Description = Group3 - Site2 (impicitly Server 1)Parent SiteID = 2 Parent ServerID = 2(May not be correct)
03-28 16:56:24.033 D/MYDBINFO: SiteID = 5 Description = Site5 - Server 1 ServerID = 1
03-28 16:56:24.033 D/MYDBINFO: Groups in Site = 0
更多
可能是您不期望结果,而是在指定所有三个参数时期望一个 Server/Site/Group。如果是这样,那么我认为使用 @Relation
不是可行的方法。相反,没有关系的 POJO 才是正确的选择。
在后面的查询中考虑 SQL 例如:-
SELECT *,sites.description AS site_description, groups.description AS group_description FROM groups
INNER JOIN sites ON sites.site_id = groups.site_id
INNER JOIN servers ON servers.server_id = sites.server_id
WHERE servers.server_id = 1 AND sites.site_id = 1 AND groups.group_id = 1;
有了上面的数据(注意sites.description AS site_description, groups.description AS group_description
是disambiguate/distinguish 来自不同表的相同列名)。
您可能会期望(当参数为 1,1,1 时):-
如上面的日志所示,这不是 Room 提供的内容。
但是考虑 POJO :-
class AltServerSiteGroup {
var server_id: Long = 0
var device_id: Long = 0
var account_id: Long = 0
var company_id: Long = 0
var site_id: Long = -1
var site_description: String = ""
var group_id: Long = -1
var group_description: String = ""
}
- 注意我改为使用 Long 而不是 Int(在
Server
中也是如此)。
然后考虑道:-
@Transaction
@Query("SELECT *, sites.description AS site_description, groups.description AS group_description FROM groups " +
"INNER JOIN sites ON sites.site_id = groups.site_id " +
"INNER JOIN servers ON servers.server_id = sites.server_id " +
"WHERE servers.server_id = :serverId AND sites.site_id = :siteId AND groups.group_id = :groupId")
fun getAlt(serverId: Long, siteId: Long, groupId: Long): List<AltServerSiteGroup>
- 如果只有 1 个值被 returned 是可能的(如果 ID 是主键,情况就是这样),则可以使用
AltServerSiteGroup
而不是List<AltServerSiteGroup>
。
因此,将以下内容添加到 MainActivity 中:-
Log.d(TAG, "Alternative Perhaps what is wanted")
val alt = allDao.getAlt(1,1,1)
for(s: AltServerSiteGroup in alt) {
logserver(Server(s.server_id,s.account_id,s.device_id,s.company_id))
logsite(Site(s.site_id,s.server_id,s.site_description))
loggroup(Group(s.group_id,s.server_id,s.site_id,s.group_description))
}
- 添加了用于记录实体的函数,因此记录了 logserver(Server(....)) 等
那么该部分的结果将是:-
03-28 19:10:41.930 D/MYDBINFO: Alternative Perhaps what is wanted
03-28 19:10:41.931 D/MYDBINFO: ServerID = 1 DeviceID = 2 AccountID = 1 CompanyID = 3
03-28 19:10:41.931 D/MYDBINFO: SiteID = 1 Description = Site1 - Server1 ServerID = 1
03-28 19:10:41.931 D/MYDBINFO: GroupID = 1 Description = Group1 - Site1 (impicitly Server 1)Parent SiteID = 1 Parent ServerID = 1(May not be correct)
即符合选择条件的单个 Server/Site/group。
您可以将功能添加到 AltServerSiteGroup 以 return 提取的 Server/Site/Group 对象,但请注意,这些将与 complete/full 对象不同,因为它们只有一个服务器站点-组例如:-
class AltServerSiteGroup {
var server_id: Long = 0
var device_id: Long = 0
var account_id: Long = 0
var company_id: Long = 0
var site_id: Long = -1
var site_description: String = ""
var group_id: Long = -1
var group_description: String = ""
fun getServer(): Server {
return Server(server_id,account_id,device_id,company_id)
}
fun getSite(): Site {
return Site(site_id,server_id,site_description)
}
fun getGroup(): Group {
return Group(group_id,server_id,site_id,group_description)
}
}
说明
简而言之,Room 将根据
@Relation
构建 complete 对象,从而添加额外的 unwanted[=170] =] 站点和组。如果您查看 Java(生成)中的 Dao 代码(使用项目 window 中的 Android 视图),请注意文件名后缀为_Impl (所以对于
的代码短很多AllDao
,如上所用,在生成的java中是AllDao_Impl
),你会看到房间是做什么的,为getAlt
构建的代码比getSiteWithGroup
.