You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 04:32:05