Scala Slick原生查询结果未聚合,如何实现Cart-Products关联格式?
解决Cart数据合并问题
当前查询返回的是每个Cart对应单个Product的分散结构,需要将同一Cart下的所有Product合并到同一个对象中,可通过以下步骤修改代码:
1. 新增中间数据类承载原始查询行
在Form包下新增一个case class,用来映射SQL查询返回的每一行扁平化数据:
package Form import slick.jdbc.GetResult // 保留原有所有case class不变,新增以下内容 case class CartProductRow(cartId: Int, productId: Int, productName: String, productPrice: Int) object CartProductRow { implicit val getCartProductResult: GetResult[CartProductRow] = GetResult(r => CartProductRow( cartId = r.<<, productId = r.<<, productName = r.<<, productPrice = r.<< ) ) }
2. 修改Repository的查询逻辑
调整UserRepository中的customquery方法,先获取原始行数据,再通过Scala的分组操作合并同一Cart下的所有Product:
package repositories class UserRepository @Inject()(val dbConfigProvider: DatabaseConfigProvider)(implicit ec: ExecutionContext) extends HasDatabaseConfigProvider[JdbcProfile] { import profile.api._ import Form.CartProductRow private val carts = TableQuery[Carts] private val cart_items = TableQuery[Cart_items] private val products = TableQuery[Products] def customquery = { // 移除SQL中未使用的mg字段,简化查询 val rawQuery = sql"""select c.cart_id,p.product_id,p.name,p.price from carts c inner join cart_items ci on c.cart_id=ci.cart_id inner join products p on ci.product_id = p.product_id join model_group mg on mg.child_model=p.product_id""".as[CartProductRow] db.run(rawQuery).map { rows => // 按cart_id分组,将同一购物车的所有商品合并 rows.groupBy(_.cartId).map { case (cartId, productRows) => Form.cartData( id = cartId, products = productRows.map(row => Form.products(row.productId, row.productName, row.productPrice) ).toSeq ) }.toSeq } } }
3. 移除无用的映射逻辑
删除Form.cartData对象中不再需要的GetResult映射,因为现在不再直接从SQL行转换cartData:
package Form import slick.jdbc.GetResult // 保留原有所有case class不变,修改cartData对象 case class cartData(id:Int,products:Seq[products]) object cartData { // 删除以下无用代码 // implicit val getCartResult = GetResult(r => cartData(r.<<,Seq(products(r.<<, r.<<, r.<<)))) }
逻辑说明
原始SQL返回的是购物车-商品的扁平化一对多结果(每个组合占一行),通过groupBy(_.cartId)将同一购物车的所有商品行聚合,再转换为cartData结构,最终就能得到单购物车对应多商品的目标格式。Controller代码无需修改,因为customquery现在返回的已经是合并后的结果,直接序列化即可生成目标JSON。
内容的提问来源于stack exchange,提问作者Vedansh Trivedi
相关产品推荐
相关产品推荐

