如何在hibernate中映射得到本机查询的结果?

时间:2017-10-16 19:26:13

标签: java hibernate

我的查询包含的列比实体类的列多。

为了不让hibernate投诉,我必须在字段中添加注释,如

@Transient
private Integer count;

但通过这样做使得hibernate无法映射计数。假设我的查询是

session.createSQLQuery("SELECT p.*, count(p.id), sqrt(1+2) as distance FROM post p group by p.id")

我知道查询没有任何逻辑意义。这仅仅是例如。从上面的查询返回的列将包含post中的所有内容以及两个额外的列,count和distance。我想将结果映射到我的entity,其中计数和距离都使用@Transient进行注释,或者是否有更好的方法来映射结果。我很乐意这样做。目标不是在实体中执行此操作,而是使用映射结果的class执行此操作。我试过打电话给addEntity(),但似乎没有帮助。

2 个答案:

答案 0 :(得分:1)

您可以使用结果集转换器来实现此目的。

步骤1)创建一个新的DTO类,其中包含您要查询的所有字段

步骤2)添加以下行

setResultTransformer( Transformers.aliasToBean(DTO.class))

示例:

List resultWithAliasedBean = session.createQuery(
  "SELECT p.*, count(p.id), sqrt(1+2) as distance FROM post p group by p.id")
  .setResultTransformer(Transformers.aliasToBean(DTO.class))
  .list();

DTO dto = (DTO) resultWithAliasedBean.get(0);

注意:确保DTO类中的字段名称与查询返回的列名称匹配。

答案 1 :(得分:0)

我看到你正在使用Hibernate所以Yathish的答案很好。

但是如果您想使用JPA规范,那么您可以使用结果集映射

Query q = em.createNativeQuery(
    "SELECT c.id, c.name, COUNT(o) as orderCount, AVG(o.price) AS avgOrder " +
    "FROM Customer c " +
    "JOIN Orders o ON o.cid = c.id " +
    "GROUP BY c.id, c.name",
    "CustomerDetailsResult");

@SqlResultSetMapping(name="CustomerDetailsResult",
    classes={
        @ConstructorResult(targetClass=com.acme.CustomerDetails.class,
            columns={
                @ColumnResult(name="id"),
                @ColumnResult(name="name"),
                @ColumnResult(name="orderCount"),
                @ColumnResult(name="avgOrder", type=Double.class)})
    })

你必须指定从SQL结果集到DTO的列的映射。

如果您认为这很复杂,那么有一个名为QLRM(Query Lanaguage Result Mapper)的开源项目可以将任何SQL语句映射到POJO。

http://simasch.github.io/qlrm/

最后但并非最不重要的是,如果你要进行大量的SQL处理,为什么不看看jOOQ:https://www.jooq.org/