通过具有ManyToOne关系的实体上的Hibernate Projections在SQL查询上使用更少的列
-
06-07-2019 - |
题
我正在尝试构建一个较小的SQL,以避免“select * from A”;正在为hibernate Criteria默认构建。
如果我使用简单字段(无关系),通过“变形金刚”,我可以设法使用这个SQL:
select description, weight from Dog;
嗨,我有这个实体:
@Entity
public class Dog
{
Long id;
String description;
Double weight;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "person_id", nullable = false)
Person owner;
}
@Entity
public class Person
{
Long id;
String name;
Double height;
Date birthDate;
}
我的目标是拥有:
select description, weight, owner.name from Dog
我尝试使用Criteria(和子标准):
Criteria dogCriteria = sess.createCriteria(Dog.class);
ProjectionList proList = Projections.projectionList();
proList.add(Projections.property("description"), description);
proList.add(Projections.property("weight"), weigth);
dogCriteria.setProjection(proList);
Criteria personCriteria = dogCriteria.createCriteria("owner");
ProjectionList ownerProList = Projections.projectionList();
ownerProList.add(Projections.property("name"), description);
dogCriteria.setProjection(ownerProList); //After this line, debugger shows that the
//projection on dogCriteria gets overriden
//and the query fails, because "name" is
//not a field of Dog entity.
我应该如何使用Projections来获得更小的SQL,更少的列? 提前谢谢。
解决方案
首先,
select description, weight, owner.name from Dog
是无效的SQL。它必须是
之类的东西select description, weight, Person.name
from Dog join Person on Dog.person_id = Person.id
代替。其次,为什么?虽然可以做你想做的事情(见下文),但是通过Criteria API这样做是非常冗长的,你无法获得任何显示效果。除非所述列是巨大的blob或者您选择了数十万条记录,否则几列的数据传输节省可以忽略不计。在任何一种情况下,都有更好的方法来处理这个问题。
Anywho,为了做你想要的标准,你需要通过别名加入链接表(Person),并使用所述别名指定主标准的投影:
Criteria criteria = session.createCriteria(Dog.class, "dog")
.createAlias("owner", "own")
.setProjection( Projections.projectionList()
.add(Projections.property("dog.description"))
.add(Projections.property("dog.weight"))
.add(Projections.property("own.name"))
);
Criteria Projections文档。请记住,执行时,上述条件将返回对象数组列表。您需要指定 ResultTransformer 为了将结果转换为实际对象。
其他提示
我自己没有尝试过,但我认为你也可以在你的实体(Pojo)中使用另一个构造函数并将列传递给那里。 请参见 https://www.thoughts-on-java.org/hibernate-最佳实践/ 章节“1.2 Pojo”详细说明。 对我而言,目前尚不清楚这是否也适用于ManyToOne关系。我试试看。
不隶属于 StackOverflow