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

时间:2011-10-04 03:42:27

标签: grails gorm

我需要获得每个商店每个订单销售的所有商品的总和。我正在使用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]

}

我认为withCriteria()会更容易阅读,但我无法弄清楚如何使用sum()中的表达式这样做是不明显的原因。

projections {
  sum("soldPrice * soldQuantity")
}

由于

4 个答案:

答案 0 :(得分:10)

您可以选择两种方式。

选项1

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

OrderItem {
  BigDecimal soldPrice
  Integer soldQuantity
  BigDecimal totalPrice

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

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

}

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

projections {
    sum("totalPrice")
}

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

BigDecimal getTotalPrice() {
    totalPrice ?: (soldPrice && soldQuantity) ? soldPrice * soldQuantity : null
}

但是如果你在持久化之前需要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")
 }

注意

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

答案 1 :(得分:1)

我尝试将derived property total暂时添加到OrderItem并在其上使用sum()

答案 2 :(得分:1)

从Grails 2.2开始,支持SQL投影,而不必下载到Hibernate Criteria API。请注意,公式映射可能仍然更合适,但有了这个,您可以根据您的问题直接实现总和('soldPrice * soldQuantity')样式投影。

http://grails.org/doc/latest/guide/single.html#criteria

答案 3 :(得分:0)

尝试SQL Projection

projections {
  sqlProjection 'sum("soldPrice * soldQuantity") as total', 'total', StandardBasicTypes.DOUBLE
}

进一步了解详情 http://docs.grails.org/2.5.6/guide/GORM.html#criteria