Return type for Android Room joins

前端 未结 5 1103
谎友^
谎友^ 2020-11-28 23:31

Let\'s say I want to do an INNER JOIN between two entities Foo and Bar:

@Query(\"SELECT * FROM Foo INNER JOIN Bar ON F         


        
5条回答
  •  半阙折子戏
    2020-11-29 00:18

    Try this way. For example, I have M2M (many-to-many) relations between Product and Attribute. Many Products have many Attributes and I need to get all Attributes by Product.id with sorted records by PRODUCTS_ATTRIBUTES.DISPLAY_ORDERING.

    |--------------|  |--------------|  |-----------------------|
    | PRODUCT      |  | ATTRIBUTE    |  | PRODUCTS_ATTRIBUTES   |
    |--------------|  |--------------|  |-----------------------|
    | _ID:  Long   |  | _ID: Long    |  | _ID: Long             |
    | NAME: Text   |  | NAME: Text   |  | _PRODUCT_ID: Long     |
    |______________|  |______________|  | _ATTRIBUTE_ID: Long   |
                                        | DISPLAY_ORDERING: Int |
                                        |_______________________|
    

    So, models will be like below:

    @Entity(
        tableName = "PRODUCTS",
        indices = [
            Index(value = arrayOf("NAME"), unique = true)
        ]
    )
    class Product {
    
        @PrimaryKey(autoGenerate = true)
        @ColumnInfo(name = "_ID")
        var _id: Long = 0
    
        @ColumnInfo(name = "NAME")
        @SerializedName(value = "NAME")
        var name: String = String()
    
    }
    
    
    @Entity(
        tableName = "ATTRIBUTES",
        indices = [
            Index(value = arrayOf("NAME"), unique = true)
        ]
    )
    class Attribute {
    
        @PrimaryKey(autoGenerate = true)
        @ColumnInfo(name = "_ID")
        var _id: Long = 0
    
        @ColumnInfo(name = "NAME")
        @SerializedName(value = "NAME")
        var name: String = String()
    
    }
    

    And the "join" table will be:

    @Entity(
        tableName = "PRODUCTS_ATTRIBUTES",
        indices = [
            Index(value = ["_PRODUCT_ID", "_ATTRIBUTE_ID"])
        ],
        foreignKeys = [
            ForeignKey(entity = Product::class, parentColumns = ["_ID"], childColumns = ["_PRODUCT_ID"]),
            ForeignKey(entity = Attribute::class, parentColumns = ["_ID"], childColumns = ["_ATTRIBUTE_ID"])
        ]
    )
    class ProductAttribute {
    
        @PrimaryKey(autoGenerate = true)
        @ColumnInfo(name = "_ID")
        var _id: Long = 0
    
        @ColumnInfo(name = "_PRODUCT_ID")
        var _productId: Long = 0
    
        @ColumnInfo(name = "_ATTRIBUTE_ID")
        var _attributeId: Long = 0
    
        @ColumnInfo(name = "DISPLAY_ORDERING")
        var displayOrdering: Int = 0
    
    }
    

    In, AttributeDAO, to get all attributes based on Product._ID, you can do something like below:

    @Dao
    interface AttributeDAO {
    
        @Query("SELECT ATTRIBUTES.* FROM ATTRIBUTES INNER JOIN PRODUCTS_ATTRIBUTES ON PRODUCTS_ATTRIBUTES._ATTRIBUTE_ID = ATTRIBUTES._ID INNER JOIN PRODUCTS ON PRODUCTS._ID = PRODUCTS_ATTRIBUTES._PRODUCT_ID WHERE PRODUCTS._ID = :productId ORDER BY PRODUCTS_ATTRIBUTES.DISPLAY_ORDERING ASC")
        fun getAttributesByProductId(productId: Long): LiveData>
    
    }
    

    If you have any questions, please tell me.

提交回复
热议问题