在anorm中紧凑映射一对多

时间:2014-04-29 16:56:07

标签: 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 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)
    })

GoodMapping

  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
      )
    }
  }

GoodComponentMapping

  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 *)

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

1 个答案:

答案 0 :(得分:0)

Anorm不是一个ORM,因此不能提供这种自动行为,但可以使用流媒体来处理它,以便根据需要精确地聚合数据。