hibernate原生查询复杂构造函数映射
Posted
技术标签:
【中文标题】hibernate原生查询复杂构造函数映射【英文标题】:hibernate native query complex constructor mapping 【发布时间】:2018-04-14 18:55:20 【问题描述】:Java、Spring Data JPA
我有 2 个实体:
class Source
Integer id;
String name;
class Item
Integer id;
String name;
Integer sourceId;
我需要这样的统计原生查询结果:
select s.id source_id, s.name source_name, count(i.id) item_count
from source s
left join item i on s.id = i.source_id
group by s.id
我想在 Java 对象 MyResult 中得到结果:
class MyResult
Source source;
Integer itemCount;
MyResult(Source source, Integer itemCount) ...
最接近的解决方案是像这样使用@SqlResultSetMapping:
@SqlResultSetMapping(
name = "MyResultMapping",
entities =
@EntityResult(
entityClass = Source.class,
fields =
@FieldResult(name = "id", column = "source_id"),
@FieldResult(name = "name", column = "source_name"),
),
...
???
)
或
@SqlResultSetMapping(
name = "MyResultMapping",
classes =
@ConstructorResult(
targetClass = MyResult.class,
columns =
@ColumnResult(name = "???"),
???
)
)
有了第二个变种,我可以使用这样的东西:
MyResult(Integer sourceId, String sourceName, Integer itemsCount)
this.source = new Source(sourceId, sourceName);
this.itemsCount = itemsCount;
但我希望它使用@SqlResultSetMapping 自动化...(因为我的真实对象更复杂)
【问题讨论】:
【参考方案1】:使用 Spring Data JPA 最好使用projections 来实现您的需求,例如:
public interface SourceWithItemCount
Source getSource();
Integer getItemCount();
然后在您的源代码库中创建HQL 查询方法,如下所示:
public interface SourceRepo extends JpaRepository<Source, Integer>
@Query("select s as source, count(i) like itemCount from Source s left join Item i on i.sourceId = s.id group by s"
List<SourceWithItemCount> getSourcesWithItemCount();
重要说明是使用别名作为返回值(s as source
等),它允许 Spring Data JPA 将它们映射到投影属性。
Join on <condition>
适用于 Hibernate 5.1+ 版本(如果我没记错的话),所以我建议您在对象之间创建经典的 one-to-many 关系,例如:
@Entity
class Source
@Id private Integer id;
private String name;
@OneToMany @JoinColumn(name = "source_id") private List<Item> items;
@Entity
class Item
@Id private Integer id;
private String name;
然后创建所有Hibernate版本(以及其他ORM提供者)支持的JPQL查询方法:
@Query("select s as source, count(i) like itemCount from Source s left join s.items i group by s"
List<SourceWithItemCount> getSourcesWithItemCount();
【讨论】:
感谢投影链接和想法!它看起来很有用,但我的关键问题是本地查询映射(我的实体没有直接关系,我不能使用 HQL) @Elegant.Obj Hibernate 5.1+ 支持不相关实体之间的连接,因此您可以使用 HQL。以上是关于hibernate原生查询复杂构造函数映射的主要内容,如果未能解决你的问题,请参考以下文章
hibernate 为什么持久化类时必须提供一个不带参数的默认构造函数