我的查询包含的列比实体类的列多。
为了不让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()
,但似乎没有帮助。
答案 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/