你可以通过两种方式做到这一点。
您可以嵌入产品并为类别和单元(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
即两种方法的结果是相同的。