Grails使用executeQuery()计算算术表达式?

Mic*_*cor 2 grails grails-orm

我需要得到每个商店每个订单销售的所有商品的总和.我正在使用executeQuery()在表达式上运行sum().它工作得很好,如下所示,但我想知道是否有更好,更时髦的方法来做到这一点.

StoreService {
  static transactional = false

  def getTotalOrders(def store) {
    return Store.executeQuery("select sum(a.soldQuantity * a.soldPrice) as total 
             from OrderItem a inner join a.order b inner join b.store c 
             where c= :store", [store: store]).get(0)
  }
}

Store {
  transient storeService

  def getTotalSales() {
    storeService.getTotalSales()
  }

  static hasMany = [items: Item]
  // no hasMany to Order
}

Item {
  static belongsTo = [store: Store]
  // no hasMany to OrderItem
}


Order {
  static hasMany = [orderItems: OrderItem]
  static belongsTo = [store: Store]
}


OrderItem {

  BigDecimal soldPrice
  Integer soldQuantity

  static belongsTo = [order: Order, item: Item]

}
Run Code Online (Sandbox Code Playgroud)

我认为withCriteria()会更容易阅读,但我无法弄清楚如何用sum()中的表达式来做这件事并不会有明显的原因.

projections {
  sum("soldPrice * soldQuantity")
}
Run Code Online (Sandbox Code Playgroud)

谢谢

Ben*_*err 10

您可以选择两种选择.

选项1

您可以将公式映射添加到域类,然后直接查询它.

OrderItem {
  BigDecimal soldPrice
  Integer soldQuantity
  BigDecimal totalPrice

  static mapping = {
    totalPrice formula: "sold_price * sold_quantity"
  }

  static belongsTo = [order: Order, item: Item]

}
Run Code Online (Sandbox Code Playgroud)

现在您的条件查询可以包含

projections {
    sum("totalPrice")
}
Run Code Online (Sandbox Code Playgroud)

不仅如此,您还可以使用动态查找器OrderItem.findAllByTotalPriceGreaterThan(20.00)以及简单访问来查询它println "The final price is ${orderInstance.totalPrice}.我们发现这真的很漂亮,但是有时候你想要在持久保存OrderItem之前得到totalPrice所以我们通常会写一个简单的(非干)吸气剂

BigDecimal getTotalPrice() {
    totalPrice ?: (soldPrice && soldQuantity) ? soldPrice * soldQuantity : null
}
Run Code Online (Sandbox Code Playgroud)

但是如果你在持久化之前需要totalPrice,那么你只需要这种东西.

选项2

在公式映射之前,我们习惯于下拉到Hibernate Criteria API并使用sqlProjection Projection作为我们的条件查询的一部分.

projections {
    addProjectionToList(Projections.sqlProjection(
            "sum(sold_price * sold_quantity) as totalPrice",
            ["totalPrice"] as String[], 
            [Hibernate.LONG] as Type[],
        ), "sumProjection")
 }
Run Code Online (Sandbox Code Playgroud)

注意

我认为重要的是要注意在公式和sql投影中,使用数据库中的列名和数据库特定的sum语法.