0

我正在努力,但没有得到任何结果,我想获取除类别名称和单位名称之外的所有产品信息,因为我想my adapter在最佳实践中显示所有这些信息这样做,请检查我的代码。

如何编写查询以访问多个表中的数据。我需要定义哪种类型的类来涵盖所有这些数据。

@Entity(tableName = "product")
data class Product(
    @PrimaryKey(autoGenerate = true)
    val product_id: Int,

    val name: String,
    val sellPrice: Double,
    val barcode: String?,
    val buyPrice: Double?,
    val quantity: Double?,
    val packing: Double?,
    val reducePrice: Double?,
    val description: String?,

    val fk_category: Int?,
    val fk_unit: Int?
)

@Entity(tableName = "category")
data class Category(
    @PrimaryKey(autoGenerate = true)
    val category_id: Int,

    val name: String
)

@Entity(tableName = "unit")
data class Unit(
    @PrimaryKey(autoGenerate = true)
    val unit_id: Int,

    val name: String
)

data class ProductAndCategory(
    @Embedded
    val category: Category,
    @Relation(
        parentColumn = "category_id",
        entityColumn = "fk_category"
    )
    val product: Product
)

data class ProductAndUnit(
    @Embedded
    val unit: Unit,
    @Relation(
        parentColumn = "unit_id",
        entityColumn = "fk_unit"
    )
    val product: Product
)

@Dao
interface ProductDao {

    @Query("SELECT * FROM product")
    fun getAllProducts(): LiveData<List<Product>>

    @Transaction
    @Query("SELECT * FROM product INNER JOIN category on product.fk_category = category.category_id")
    fun getAllProductAndCategory(): LiveData<List<ProductAndCategory>>

    @Query("SELECT * FROM product WHERE product_id = :productID")
    suspend fun getProduct(productID: Int): List<Product>

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insertProduct(product: Product)

    @Update
    suspend fun updateProduct(product: Product)

    @Delete
    suspend fun deleteProduct(product: Product)

    @Query("DELETE FROM product")
    suspend fun deleteAllProducts()

    @Transaction
    @Query("SELECT * FROM product INNER JOIN category on product.fk_category = category.category_id WHERE product_id= :productID")
    suspend fun getProductAndCategory(productID: Int): List<ProductAndCategory>

    @Transaction
    @Query("SELECT * FROM product INNER JOIN unit on product.fk_unit = unit.unit_id WHERE product_id= :productID")
    suspend fun getProductAndUnit(productID: Int): List<ProductAndUnit>
}
4

1 回答 1

0

你可以通过两种方式做到这一点。

您可以嵌入产品并为类别和单元(2 @Realtion)设置@Relation,或者您可以嵌入所有三个。

所以你可以: -

data class ProductAndCategoryAndUnit(
    @Embedded
    val product: Product,
    @Relation(entity = Category::class, parentColumn = "fk_category",entityColumn = "category_id")
    val category: Category,
    @Relation(entity = Unit::class, parentColumn = "fk_unit",entityColumn = "unit_id")
    val unit: Unit
)

有类似的东西: -

@Query("SELECT * FROM product")
@Transaction
fun getProductAndCategoryAndUnit(): List<ProductAndCategoryAndUnit>

或交替(但请阅读注意事项):-

data class ProductCategoryUnit (
    @Embedded
    val product: Product,
    @Embedded
    val category: Category,
    @Embedded
    val unit: Unit
)

有类似的东西: -

@Query("SELECT * FROM product JOIN category ON product.fk_category = category.category_id JOIN unit ON product.fk_unit = unit.unit_id")
    fun getProductCategoryUnit(): List<ProductCategoryUnit>

注释重新第 2 次

这种替代方案会对全部命名的 3 列有问题name(它们会模棱两可)。您可以使用 @Embedded(prefix = "?") 来消除歧义,但是这需要在 SQL 中对列进行别名。一种更简单的方法是确保列名不会有歧义。这可以使用@ColumnInfo 的名称参数作为单元的示例轻松实现(类别需要类似):-

@Entity(tableName = "unit")
data class Unit(
    @PrimaryKey(autoGenerate = true)
    val unit_id: Long,
    @ColumnInfo(name = "unit_name") // ADDED to disambiguate for joins
    val name: String
)
  • 注意真正的 id 应该是 Long 而不是 Int。

两者的工作示例

根据您的代码,以下演示了两者,注意为了方便和简洁,演示在主线程上运行,因此 LiveData 和挂起的函数已相应更改。Long 也被用来代替 Int 的 id。

使用的产品数据类:-

@Entity(tableName = "product")
data class Product(
    @PrimaryKey(autoGenerate = true)
    val product_id: Long,

    val name: String,
    val sellPrice: Double,
    val barcode: String?,
    val buyPrice: Double?,
    val quantity: Double?,
    val packing: Double?,
    val reducePrice: Double?,
    val description: String?,
    val fk_category: Long?,
    val fk_unit: Long?
)

使用的类别数据类:-

@Entity(tableName = "category")
data class Category(
    @PrimaryKey(autoGenerate = true)
    val category_id: Long,
    @ColumnInfo(name = "category_name") // ADDED to disambiguate for joins
    val name: String
)

数据类 Unit 和 POJO 一样。

用于演示的 ProductDao :-

@Dao
interface ProductDao {

    @Query("SELECT * FROM product")
    fun getAllProducts(): /*LiveData<*/List<Product>/*>*/

    /*
    @Transaction
    @Query("SELECT * FROM product INNER JOIN category on product.fk_category = category.category_id")
    fun getAllProductAndCategory(): LiveData<List<ProductAndCategory>>
    */

    @Insert(onConflict = OnConflictStrategy.IGNORE)
    fun insert(unit: Unit): Long
    @Insert(onConflict = OnConflictStrategy.IGNORE)
    fun insert(category: Category): Long


    @Query("SELECT * FROM product WHERE product_id = :productID")
    suspend fun getProduct(productID: Int): List<Product>

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    /*suspend*/ fun insertProduct(product: Product)

    @Update
    suspend fun updateProduct(product: Product)

    @Delete
    suspend fun deleteProduct(product: Product)

    @Query("DELETE FROM product")
    suspend fun deleteAllProducts()

    /*
    @Transaction
    @Query("SELECT * FROM product INNER JOIN category on product.fk_category = category.category_id WHERE product_id= :productID")
    suspend fun getProductAndCategory(productID: Int): List<ProductAndCategory>
    */

    /*
    @Transaction
    @Query("SELECT * FROM product INNER JOIN unit on product.fk_unit = unit.unit_id WHERE product_id= :productID")
    suspend fun getProductAndUnit(productID: Int): List<ProductAndUnit>
    */

    @Query("SELECT * FROM product")
    @Transaction
    fun getProductAndCategoryAndUnit(): List<ProductAndCategoryAndUnit>

    @Query("SELECT * FROM product WHERE product_id=:productID")
    fun getProductAndCategoryAndUnitById(productID: Long): List<ProductAndCategoryAndUnit>

    @Query("SELECT * FROM product JOIN category ON product.fk_category = category.category_id JOIN unit ON product.fk_unit = unit.unit_id")
    fun getProductCategoryUnit(): List<ProductCategoryUnit>

}

TheDatabase类是一个很好的库存@Database,因此不包括在内。

最后是一个活动: -

class MainActivity : AppCompatActivity() {
    lateinit var db: TheDatabase
    lateinit var dao: ProductDao
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        db = TheDatabase.getInstance(this)
        dao = db.getProductDao()

        var u1 = dao.insert(Unit(0L, "Unit1"))
        var u2 = dao.insert(Unit(0L, "Unit2"))

        var c1 = dao.insert(Category(0L,"Cat1"))
        var c2 = dao.insert(Category(0L,"Cat2"))

        dao.insertProduct(Product(0L,"Produuct1",1.1,"Barcode001",2.2,10.5,0.0,0.0,"Desc4Product1",c2,u1))
        dao.insertProduct(Product(0L,"Product2",1.1,"Barcode002",2.2,10.5,0.0,0.0,"Desc4product2",c1,u2))

        // Inserts Catergory,Unit and Product (utilising the id returned by the inserts for the category and Unit)
        dao.insertProduct(
            Product(
                0L,"" +
                        "Product3",
                1.1,"" +
                        "Barcode003",
                2.2,
                10.5,
                0.0,
                0.0,
                "Desc4Product3",
                dao.insert(Category(0L,"Cat4")),
                dao.insert(Unit(0L,"Unit4"))
            )
        )

        // Extract and Log via the @Embedded and 2 @Realtion's
        for(pcu: ProductAndCategoryAndUnit in dao.getProductAndCategoryAndUnit()) {
            Log.d("PRODUCTINFO","Product is ${pcu.product.name} .... Category is ${pcu.category.name} Unit is ${pcu.unit.name}")
        }
        // Extract and Log via the 3 @Embedded's
        for(pcu: ProductCategoryUnit in dao.getProductCategoryUnit()) {
            Log.d("PRODUCTINFO","Product is ${pcu.product.name} .... Category is ${pcu.category.name} Unit is ${pcu.unit.name}")
        }
    }
}

日志中的结果:-

D/PRODUCTINFO: Product is Produuct1 .... Category is Cat2 Unit is Unit1
D/PRODUCTINFO: Product is Product2 .... Category is Cat1 Unit is Unit2
D/PRODUCTINFO: Product is Product3 .... Category is Cat4 Unit is Unit4


D/PRODUCTINFO: Product is Produuct1 .... Category is Cat2 Unit is Unit1
D/PRODUCTINFO: Product is Product2 .... Category is Cat1 Unit is Unit2
D/PRODUCTINFO: Product is Product3 .... Category is Cat4 Unit is Unit4

即两种方法的结果是相同的。

于 2021-08-16T15:17:54.887 回答