ver*_*rdy 4 java spring hibernate hql pojo
过去几周我一直在使用spring和hibernate,我一直在那里学习新东西.
现在我有一个问题,我想用Hibernate中的Projections来解决.
假设有一个模型Person,该模型有很多Car.以下是类定义大致如下所示:
public class Person implements java.io.Serializable {
private Integer id;
private String name;
private List<Car> cars;
private Integer minYear; // Transient
private Integer maxYear; // Transient
}
public class Car implements java.io.Serializable {
private Integer id;
private Integer year;
}
Run Code Online (Sandbox Code Playgroud)
这里的问题是我希望得到每个人的minYear(maxYear)Person最早的年份(最近一年)cars.
后来我找到了一个使用的解决方案,Projections但我偶然发现org.hibernate.QueryException: could not resolve property: minYear of: model.Person,这是db操作的代码:
Criteria criteria = sessionFactory.getCurrentSession().createCriteria("model.Person");
criteria.add(create(personInstance));
criteria.createAlias("minYear", "minYear");
criteria.setProjection(Projections.min("cars.year").as("minYear"));
Run Code Online (Sandbox Code Playgroud)
无论如何都要将聚合值存储在transient方法中,Projections因为我只想尽可能避免使用普通的SQL和HQL.
没关系,我找到了解决方案.
首先,我们需要像这样创建关联对象的别名
Criteria criteria = sessionFactory.getCurrentSession().createCriteria("model.Person");
criteria.createAlias("cars", "cars");
Run Code Online (Sandbox Code Playgroud)使用Hibernate Projections选择所需的内容
ProjectionList projections = Projections.projectionList();
projections.add(Projections.property("id").as("id"));
projections.add(Projections.property("name").as("name"));
projections.add(Projections.property("cars").as("cars"));
Run Code Online (Sandbox Code Playgroud)根据根实体对结果进行分组(在本例中使用其id,Person.id),尤其是在与聚合一起使用以对聚合进行分组时
projections.add(Projections.groupProperty("id"));
Run Code Online (Sandbox Code Playgroud)使用聚合函数
projections.add(Projections.min("cars.year").as("minYear"));
projections.add(Projections.max("cars.year").as("maxYear"));
Run Code Online (Sandbox Code Playgroud)设置投影
criteria.setProjection(projections);
Run Code Online (Sandbox Code Playgroud)使用结果转换器AliasToBeanResultTransformer将结果字段(如步骤2和4中所指定)映射到POJO
criteria.setResultTransformer(new AliasToBeanResultTransformer(Person.class));
Run Code Online (Sandbox Code Playgroud)得到结果
List<Person> results = (List<Person>) criteria.list();
Run Code Online (Sandbox Code Playgroud)