7

考虑表

sales (id, seller_id, amount, date)

这是sales使用查询生成的视图SELECT seller_id, SUM(amount) FROM sales GROUP BY seller_id

total_sales (seller_id, amount)

我想为总销售额创建一个实体,但没有 sql 端的视图。

该实体将从查询构造。我发现的最接近的是this,但我无法让它工作。

即使我定义了加载器,hibernate 也会查找实体的表,如果找不到它会给出错误。如果我创建表,它不会从我定义的命名查询中加载实体,Hibernate 会自行生成查询。

有没有办法让@Loader 工作,或者有另一种方法可以将查询映射到实体?

4

4 回答 4

19

为什么不在new查询中使用?

select new TotalSales(seller_id, count(seller_id))
from sales
group by seller_id

您只需编写一个 TotalSales 类,其构造函数采用 Seller_id 和一个整数。


编辑:使用标准 API 时,您可以使用AliasToBeanResultTransformer(参见API 文档)。它将每个别名复制到同名的属性。

 List list = s.createCriteria(Sales.class)
  .setProjection(Projections.projectionList()
    .add( Projections.property("id"), "SellerId" )
    .add( Projections.rowCount("id"), "Count" ) )
  .setResultTransformer( 
    new AliasToBeanResultTransformer(TotalSales.class) )
  .list();

然后你TotalSales需要一个SellerIdCount属性。

于 2009-09-11T12:02:45.537 回答
0

除了 Stefan 的回答,您还可以使用显式 HQL 查询

    SELECT seller_id, SUM(amount) FROM sales GROUP BY seller_id

结果自然存储在 List 中。如果此数据类型对您不方便,您可以:

  • 用它们创建新的 TotalSale 对象(使用 Stefan 的答案可能会更好)
  • 创建一个 Map 来存储数据(您也可以将其直接嵌入到请求中)。
于 2009-09-11T12:12:03.267 回答
0

您可以尝试定义一个自定义的加载器。我从来没有使用过这个,但它似乎是合理的:

<sql-query name="totalSale">
    <return alias="ts" class="TotalSale" />
    SELECT seller_id as {ts.seller_id}, SUM(amount) as ts.amount 
    FROM sales 
    WHERE seller_id = ?
    GROUP BY seller_id
</sql-query>

不确定是否需要 Seller_id 上的过滤器。

您在类映射中引用此命名查询:

<class name="TotalSale">
    <id name="seller_id">
        <generator class="increment"/>
    </id>
    <property name="seller_id" />
    <property name="amount" />
    <loader query-ref="totalSale"/>
</class>

手册中有更多细节

或者,您可以直接使用代码中的名称查询,这样您就不需要 TotalSale 的映射,也不必在代码中编写查询。命名查询也可以返回对象。请参阅文档中有关命名查询的详细信息。

于 2009-09-18T07:04:30.560 回答
0

如果您真的只想要一个特定实体来完成这项工作,您可以在自定义属性上使用“公式”

<class name="SellerSales" table="Sales" lazy="true">
    <id name="SellerId" column="SellerId" type="int">
        <generator class="native" />
    </id>
    <property name="SalesSum" type="float" update="false" insert="false" 
            formula="select SUM(sal.ammount) from sales sal where sal.seller_id = SellerId)" />
</class>

public class SellerSales
{
    public int SellerId {get; set;}
    public float SalesSum {get; set;}
}

因此,它可以访问标准引擎以进行排序、限制等,我认为这是您想要使用它的原因。

于 2009-09-18T11:27:12.660 回答