如何使用Hibernate Projection检索复杂的类及其成员?
我有一个类,需要使用Hibernate从DB检索。 问题是我的class级有多个成员,其中大多数是class级,我该如何找回它们?
@Entity public class Student { @Id long id; String name; String fname; @OneToMany List courses; @ManyToOne Dealer dealer; ... } @Entity public class Dealer { @Id long id; String name; @OneToMany(fetch = FetchType.LAZY, mappedBy = "cr.dealer", cascade = CascadeType.ALL) Set cars = new HashSet(0); .. }
我需要检索学生ID 1及其所有课程,经销商和经销商汽车列表。
我的预测如下,但它不会返回任何内容。
... .setProjection(Projections.projectionList() .add(Projections.property("friends.cars").as("cars") ...
因为您有一个课程列表和一组汽车,您只需在一个查询中获取整个图表:
select s from Student s left join fetch s.courses left join fetch s.dealer d left join fetch d.cars where s.id = :id
因为您要获取两个集合,所以此查询将生成笛卡尔积,因此您需要确保所选子集合没有太多条目。
如果你不想要遇到笛卡尔积,你可以简单地运行这个查询:
select s from Student s left join fetch s.courses left join fetch s.dealer d where s.id = :id
然后您访问dealer.cars以使用单独的查询获取该集合:
Student s = ...; s.getDealer().getCars().size();
// Projection is not needed, Hibernate will load child values as shown below Student student = session.get(Student.class); List courses = student.getCourses(); Dealer dealer = student.getDealer(); // If u want records only where child records are present, u can use LEFT_OUTER_JOIN Criteria criteria = getHibernateSession().createCriteria(Student.class); criteria.createAlias("Course", "Course", JoinType.LEFT_OUTER_JOIN); // If u want to use Projections for performance, u have to add each and every column in projection Criteria criteria = getHibernateSession().createCriteria(A.class); criteria.createAlias("b", "b", JoinType.INNER_JOIN); criteria.createAlias("br", "br", JoinType.INNER_JOIN); criteria.createAlias("bc", "bc", JoinType.LEFT_OUTER_JOIN); ProjectionList projectionList = Projections.projectionList(); projectionList.add(Projections.groupProperty("column1")); projectionList.add(Projections.property("column2")); projectionList.add(Projections.property("column3")); criteria.setProjection(projectionList); criteria.setResultTransformer(Transformers.aliasToBean(Table.class));
如果高性能不是一个问题,那么你应该让Hibernate完成他的工作。 只需使用你实体的getter。 举个例子:
Student student1 = session.get(Student.class, 1L); List courses = student1.getCourses(); Dealer dealer = student1.getDealer(); Set cars = dealer.getCars();
我不确定您是否可以使用QueryOver,但这对于这类任务来说非常容易。
Student student = null; Dealer dealer = null; Course course = null; Car car = null; var myStudent = Session.QueryOver(() => student) .Left.JoinQueryOver(() => student.courses, () => courses) .Left.JoinQueryOver(() => student.dealer, () => dealer) .Left.JoinQueryOver(() => dealer.cars, () => car) .SelectList(list => list .Select(() => student.Name) .Select(() => student.Age) .Select(() => courses.Description) .Select(() => dealer.locaiton) .Select(() => car.Model)) .TransformUsing(Transformers.AliasToBean()) .List ().AsQueryable();
创建StudentModel DTO以获得结果。 这只是一个开始的提示,您可以根据您的要求进行修改。 我希望这会奏效。 🙂
- ClassNotFoundException:org.eclipse.xtext.junit_2.4.3.v201309030823找不到junit.framework.TestCase
- 无法在旧版本的JUnit上运行简单的JUnit TestCase
- 是否可以在Hibernate / JPA中动态定义列名?
- 在内存数据库中使用Hibernate和H2时出错
- Hibernate在EntityTuplizerFactory.constructTuplizer中失败并出现NullPointerException? 为什么?
- 在Spring启动应用程序中未在多个数据库中创建表
- @Transient不在hibernate中工作
- Hibernate使用嵌入的ElementCollection抛出ConcurrentModificationException
- 在独立应用程序中的hibernate中配置sessionFactory
- Hibernate 3.5.x:NoSuchMethodError:javax.persistence.OneToMany.orphanRemoval
- ClassCastException在Hibernate / Spring 4升级后,无法将Proxy36强制转换为SessionImplementor