我需要获得每个商店每个订单销售的所有商品的总和。我正在使用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")
}
由于
答案 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')样式投影。
答案 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