Android房间内的三向交叉表

Android房间内的三向交叉表,android,sqlite,relational-database,android-room,Android,Sqlite,Relational Database,Android Room,我正在努力实现以下目标 我有以下实体 @Entity(tableName = "workspace_table") data class WorkSpace( @PrimaryKey val workSpaceId:Long, ..... ) @Entity(tableName = "widget_table") data class Widget( val widgetId:Long, ....... ) @E

我正在努力实现以下目标

我有以下实体

@Entity(tableName = "workspace_table")
data class WorkSpace(
    @PrimaryKey
    val workSpaceId:Long,
    .....
)

@Entity(tableName = "widget_table")
data class Widget(
    val widgetId:Long,
    .......
)

@Entity(tableName = "feed_table")
data class Feed(
    val feedId:Long,
    .......
)
我想从下面的3个表中得到什么 波乔

基本上,工作区和小部件、小部件和提要之间存在多对多关系 当所有三张桌子都参与时,他们应该走到一起

我看了导游

并尝试在小部件和工作区以及提要和小部件之间双向映射 然而,那些我甚至不能用它来建造的东西

我用工作区和小部件尝试了一对多,用小部件和提要尝试了多对多 然后,我在我的工作区中得到我不想要的小部件的提要

在这一点上,我真的很困惑,任何朝着正确方向的轻推都将得到极大的赞赏

更新

@Entity(
    tableName = "workspace_table",
)
data class WorkSpace(
    @PrimaryKey
    val workSpaceId:Long,
    val workPlaceName: String
)
@Database(entities = [WorkSpace::class,Widget::class,Feed::class,WorkSpaceWidgetFeedIntersectionMap::class],version = 1)
abstract class MyDatabase: RoomDatabase() {
    abstract fun getAllDoa(): AllDao
}
下面是迈克的回答,我明白了

2021-04-04 12:16:06.097 10237-10291/com.example.datacreation D/MainActivty: meta data [IntersectionWithWorkSpaceWidgetFeed(workSpace=WorkSpace(workSpaceId=2, 
associatedUserId=test, workSpaceName=Demo),
 widget=WidgetMetaData(widgetId=11, widgetName=Widget1, backgroundColor=None, widgetType=Normal, dataUrl=www), 
feed=Feed(feedId=2, feedName=Feed2, count=0, asyncInterval=1234)),
 IntersectionWithWorkSpaceWidgetFeed(workSpace=WorkSpace(workSpaceId=2, associatedUserId=test, 
workSpaceName=Demo),
 widget=WidgetMetaData(widgetId=12, widgetName=Widget2, backgroundColor=None, widgetType=normal, dataUrl=www), 
feed=Feed(feedId=1, feedName=Feed1, count=2, asyncInterval=1234)),
 IntersectionWithWorkSpaceWidgetFeed(workSpace=WorkSpace(workSpaceId=2, associatedUserId=igvuser, workSpaceName=Demo),
 widget=WidgetMetaData(widgetId=13, widgetName=Widget3, backgroundColor=None, widgetType=normal, dataUrl=www),
 feed=Feed(feedId=2, feedName=Feed2, count=0, asyncInterval=1234))]

离我原来的MergedData POJO足够近了。谢谢你,迈克。

我想你需要一个三向映射表。每行由3列组成,工作空间ID、WidgetId和FeedId,主键由所有3列组成

假设这是一个工作示例:-

3个基本实体:

工作区

@Entity(
    tableName = "workspace_table",
)
data class WorkSpace(
    @PrimaryKey
    val workSpaceId:Long,
    val workPlaceName: String
)
@Database(entities = [WorkSpace::class,Widget::class,Feed::class,WorkSpaceWidgetFeedIntersectionMap::class],version = 1)
abstract class MyDatabase: RoomDatabase() {
    abstract fun getAllDoa(): AllDao
}
小部件

@Entity(
    tableName = "widget_table",

)
data class Widget(
    @PrimaryKey
    val widgetId:Long,
    val widgetName: String
)
提要

@Entity(tableName = "feed_table")
data class Feed(
    @PrimaryKey
    val feedId:Long,
    val feedName: String
)
新映射表WorkSpaceWidgetFeedIntersectionMap

@Entity(
    tableName = "workspace_widget_feed_mapping_table",
    foreignKeys = [
        ForeignKey(
            entity = WorkSpace::class,
            parentColumns = ["workSpaceId"],
            childColumns = ["workSpaceId_map"]
        ),
        ForeignKey(
            entity = Widget::class,
            parentColumns = ["widgetId"],
            childColumns = ["widgetId_map"]
        ),
        ForeignKey(
            entity = Feed::class,
            parentColumns = ["feedId"],
            childColumns = ["feedId_map"]
        )
    ],
    primaryKeys = ["workSpaceId_map","widgetId_map","feedId_map"],
)
data class WorkSpaceWidgetFeedIntersectionMap(

    @NonNull
    val workSpaceId_map: Long,
    @NonNull
    val widgetId_map: Long,
    @NonNull
    val feedId_map: Long
)
  • 外键是可选的
道的AllDao

@Dao
interface AllDao {

    @Insert
    fun insertWorkSpace(workSpace: WorkSpace): Long
    @Insert
    fun insertWidget(widget: Widget): Long
    @Insert
    fun insertFeed(feed: Feed): Long
    @Insert
    fun insertWorkSpaceWidgetFeedMap(workSpaceWidgetFeedIntersectionMap: WorkSpaceWidgetFeedIntersectionMap): Long


    @Query("DELETE FROM workspace_table")
    fun clearWorkSpaceTable(): Int
    @Query("DELETE FROM widget_table")
    fun clearWidgetTable(): Int
    @Query("DELETE FROM feed_table")
    fun clearFeedTable(): Int

    @Query("DELETE FROM workspace_widget_feed_mapping_table")
    fun clearWorkSpaceWidgetFeedMap(): Int

    @Query("SELECT * FROM workspace_widget_feed_mapping_table")
    fun getWorkSpaceWidgetFeedIntersections(): List<WorkSpaceWidgetFeedIntersectionMap>

}
最后是一个活动MainActivity,用于测试基本功能

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.getAllDoa()
        clearAllTables(dao)
        dao.insertWorkSpace(WorkSpace(1,"WorkSpace 1"))
        dao.insertWorkSpace( WorkSpace(2,"WorkSpace 2"))

        dao.insertWidget(Widget(1,"Widget 1"))
        dao.insertWidget(Widget(2,"Widget 2"))

        dao.insertFeed(Feed(1,"Feed 1"))
        dao.insertFeed( Feed(2,"Feed 2"))

        dao.insertWorkSpaceWidgetFeedMap(WorkSpaceWidgetFeedIntersectionMap(1,1,2))
        dao.insertWorkSpaceWidgetFeedMap(WorkSpaceWidgetFeedIntersectionMap(1,1,1))
        dao.insertWorkSpaceWidgetFeedMap(WorkSpaceWidgetFeedIntersectionMap(2,1,2))
        dao.insertWorkSpaceWidgetFeedMap(WorkSpaceWidgetFeedIntersectionMap(2,2,1))

        val wwfiList = dao.getWorkSpaceWidgetFeedIntersections()
        for(cwwfi: WorkSpaceWidgetFeedIntersectionMap in wwfiList) {
            Log.d("WWFIINFO","WorkSpaceID = " + cwwfi.workSpaceId_map + " WidgetID = " + cwwfi.widgetId_map + " FeedID = " + cwwfi.feedId_map)
        }

    }

    private fun clearAllTables(dao: AllDao) {
        dao.clearWorkSpaceWidgetFeedMap()
        dao.clearFeedTable()
        dao.clearWidgetTable()
        dao.clearWorkSpaceTable()
    }
}
  • 获取数据库的生成版本(为了方便和简洁,允许在主线程上运行)
  • 拿到刀
  • 清除所有表(使测试重新命名)
  • 添加2个工作区、2个小部件和2个提要
  • 添加交叉点地图条目
  • 提取并记录交叉点
  • 结果

    @Entity(
        tableName = "widget_table",
    
    )
    data class Widget(
        @PrimaryKey
        val widgetId:Long,
        val widgetName: String
    )
    
    运行上述操作将产生:-

    2021-04-04 08:31:02.942 D/WWFIINFO: WorkSpaceID = 1 WidgetID = 1 FeedID = 2
    2021-04-04 08:31:02.942 D/WWFIINFO: WorkSpaceID = 1 WidgetID = 1 FeedID = 1
    2021-04-04 08:31:02.942 D/WWFIINFO: WorkSpaceID = 2 WidgetID = 1 FeedID = 2
    2021-04-04 08:31:02.943 D/WWFIINFO: WorkSpaceID = 2 WidgetID = 2 FeedID = 1
    
    • 然后,您可以很容易地从检索到的WorkSpaceWidgetFeedIntersectionMap中获取相应的工作区、Wdiget和提要
    • 见补充
    附加的

    现在获取您的合并数据(等效),然后考虑上面的

    的下列补充
  • 新数据类与WorkspaceWidgetFeed相交
  • :-

  • 一个额外的Dao函数getWorkSpaceWidgetAndFeedFromIntersectionMap()
  • :-

    上述变化的结果如下:-

    2021-04-04 09:20:34.371 D/WWFINFO: WorkSpaceID = 1 WorkSpaceName = WorkSpace 1 WidgetID = 1 WidgetName = Widget 1 FeedID = 2 FeedName = Feed 2
    2021-04-04 09:20:34.371 D/WWFINFO: WorkSpaceID = 1 WorkSpaceName = WorkSpace 1 WidgetID = 1 WidgetName = Widget 1 FeedID = 1 FeedName = Feed 1
    2021-04-04 09:20:34.371 D/WWFINFO: WorkSpaceID = 2 WorkSpaceName = WorkSpace 2 WidgetID = 1 WidgetName = Widget 1 FeedID = 2 FeedName = Feed 2
    2021-04-04 09:20:34.371 D/WWFINFO: WorkSpaceID = 2 WorkSpaceName = WorkSpace 2 WidgetID = 2 WidgetName = Widget 2 FeedID = 1 FeedName = Feed 1
    

    非常感谢!!。我会落实这个答案,然后回来接受它。迈克,你是个救生员,它在工作。只需最后一个查询就可以获得1个工作区,其中包含小部件列表,而该小部件包含提要列表是不可能通过Room获得的,对吗?(例如MergedData类)我必须对该数据进行一些Kotlin转换,对吗?
        val iwwfList= dao.getWorkSpaceWidgetAndFeedFromIntersectionMap()
        for(iwwf: IntersectionWithWorkSpaceWidgetFeed in iwwfList) {
            Log.d("WWFINFO","WorkSpaceID = " + iwwf.workSpace.workSpaceId + " WorkSpaceName = " + iwwf.workSpace.workPlaceName +
                    " WidgetID = " + iwwf.widget.widgetId + " WidgetName = " + iwwf.widget.widgetName +
                    " FeedID = " + iwwf.feed.feedId + " FeedName = " + iwwf.feed.feedName
            )
        }
    
    2021-04-04 09:20:34.371 D/WWFINFO: WorkSpaceID = 1 WorkSpaceName = WorkSpace 1 WidgetID = 1 WidgetName = Widget 1 FeedID = 2 FeedName = Feed 2
    2021-04-04 09:20:34.371 D/WWFINFO: WorkSpaceID = 1 WorkSpaceName = WorkSpace 1 WidgetID = 1 WidgetName = Widget 1 FeedID = 1 FeedName = Feed 1
    2021-04-04 09:20:34.371 D/WWFINFO: WorkSpaceID = 2 WorkSpaceName = WorkSpace 2 WidgetID = 1 WidgetName = Widget 1 FeedID = 2 FeedName = Feed 2
    2021-04-04 09:20:34.371 D/WWFINFO: WorkSpaceID = 2 WorkSpaceName = WorkSpace 2 WidgetID = 2 WidgetName = Widget 2 FeedID = 1 FeedName = Feed 1