2011-10-04 60 views
2

我需要获得每个商店每个订单所售出的所有商品的总和。我使用executeQuery()在表达式上运行sum()。它工作正常,如下图所示,但我想知道是否有更好的,更方便的方法来做到这一点。使用executeQuery()对算术表达式进行Grails投影?

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()会更容易阅读,但我无法弄清楚如何使用款项中的表达式做()不会采取明显的原因。

projections { 
    sum("soldPrice * soldQuantity") 
} 

感谢

回答

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的一直坚持之前,所以我们平时写一个简单的(不干燥)的吸气

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

但是你只需要这样的事情,如果你的时候,你会想totalPrice在持续之前需要totalPrice。

选项2

公式映射之前,我们使用到Hibernate的标准API下降,使用sqlProjection投影作为我们的标准查询的一部分。

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

注意

我认为值得注意的是,公式和SQL投影无论是在使用数据库列名和数据库的特定和语法是很重要的。

+0

谢谢您的建议。我们已经使用getTotalPrice()作为一个瞬态,并将totalPrice映射作为公式是一个很好的建议。 – Micor

+0

你可以根据映射订购吗? –

1

我想尝试一过derived propertytotal添加到OrderItem并在其上使用sum()

1

从Grails 2.2开始,无需下载到Hibernate Criteria API即可支持SQL预测。请注意,公式映射可能仍然更合乎需要,但通过这种方式,您可以根据您的问题直接实现总和('soldPrice * soldQuantity')风格投影。

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