hibernate native 查询复杂构造函数映射
hibernate native query complex constructor mapping
Java、Spring 数据 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 实现自动化...(因为我的真实对象更复杂)
使用 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;
}
然后创建 JPQL 所有版本的 Hibernate(和其他 ORM 提供程序)支持的查询方法:
@Query("select s as source, count(i) like itemCount from Source s left join s.items i group by s"
List<SourceWithItemCount> getSourcesWithItemCount();
Java、Spring 数据 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 实现自动化...(因为我的真实对象更复杂)
使用 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;
}
然后创建 JPQL 所有版本的 Hibernate(和其他 ORM 提供程序)支持的查询方法:
@Query("select s as source, count(i) like itemCount from Source s left join s.items i group by s"
List<SourceWithItemCount> getSourcesWithItemCount();