Scala anorm中的一对多紧映射

Scala anorm中的一对多紧映射,scala,orm,anorm,Scala,Orm,Anorm,我有两个实体 好 case class Good( var id: Long = null.asInstanceOf[Long], var name: String, var cost: Money = Moneys.ZERO, var category: String, var goodComponents: List[GoodComponent] = List.empty ) GoodComponent case class GoodComponent( var i

我有两个实体

case class Good(
  var id: Long = null.asInstanceOf[Long],
  var name: String,
  var cost: Money = Moneys.ZERO,
  var category: String,
  var goodComponents: List[GoodComponent] = List.empty
)
GoodComponent

case class GoodComponent(
  var id: Long = null.asInstanceOf[Long],
  var goodId: Long = null.asInstanceOf[Long],
  var product: Product,
  var productAmount: Int
)
现在,我装载这样的货物:

 DB.withConnection(implicit connection => {
      SQL("""
        select
          goods.*, good_components.*, products.*
        from
          goods
        left join good_components
          on goods.good__id = good_components.good_component__good_id
        left join products
          on good_components.good_component__product_id = products.product__id
        order by
          goods.good__id
      """)
      .as(GoodMapping ~ (GoodComponentMapping ?) *)
      .groupBy(_._1)
      .map({
        case (good: Good, goodComponents: List[(Good ~ Option[GoodComponent])]) => {
          good.copy(goodComponents = goodComponents.map({case (_ ~ goodComponent) => { goodComponent }}).flatten)
        }
      })
      .toList
      .sortWith(($1, $2) => $1.id < $2.id)
    })
GoodComponentMapping

  val GoodMapping = {
    get[Long]("good__id") ~
    get[String]("good__name") ~
    get[Int]("good__cost_rubles") ~
    get[Int]("good__cost_kopeks") ~
    get[String]("good__category") map {
      case goodId ~ goodName ~ goodCostRubles ~ goodCostKopeks ~ goodCategory => Good(
        goodId,
        goodName,
        new Money(
          goodCostRubles,
          goodCostKopeks
        ),
        goodCategory,
        List.empty
      )
    }
  }
  val GoodComponentMapping = {
    get[Long]("good_components.good_component__id") ~
    get[Long]("good_components.good_component__good_id") ~
    get[Long]("good_components.good_component__product_id") ~
    get[Int]("good_components.good_component__product_amount") ~
    get[Long]("products.product__id") ~
    get[String]("products.product__name") ~
    get[Long]("products.product__units") ~
    get[String]("products.product__category") map {
      case goodComponentId ~ goodComponentGoodId ~ goodComponentProductId ~ goodComponentProductAmount ~ productId ~ productName ~ productUnit ~ productCategory => GoodComponent(
        goodComponentId,
        goodComponentGoodId,
        new Product(
          productId,
          productName,
          ProductUnits.byId(productUnit).getOrElse({
            throw new IllegalArgumentException("Product unit #{" + productUnit + "} not found.")
          }),
          productCategory
        ),
        goodComponentProductAmount
      )
    }
  }
我认为需要在映射和加载商品上创建

SQL("...").as(GoodMapping *)

我想得到建议。这比我现在好吗?如何更优雅地映射good(使用goodComponents列表)?

Anorm不是ORM,因此不提供此类automagic行为,但可以根据需要使用流式处理聚集数据。

我认为Anorm没有办法做到这一点。不幸的是,Anorm只是将行映射到行,并且没有将多行从联接折叠为一行的机制。