2015-04-17 25 views
12

我有一個類,如下需要使用Hibernate從數據庫中檢索。 問題是我的課有多個成員,他們中的大多數都是班級,我如何檢索他們?如何使用Hibernate Projection檢索複雜的類及其成員?

@Entity 
public class Student { 
    @Id 
    long id; 
    String name; 
    String fname; 
    @OneToMany 
    List<Course> courses; 
    @ManyToOne 
    Dealer dealer; 
    ... 
} 

@Entity 
public class Dealer { 
    @Id 
    long id; 
    String name; 
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "cr.dealer", cascade = CascadeType.ALL) 
    Set<Car> cars = new HashSet<Cars>(0); 
    .. 

} 

我需要檢索學生id 1及其所有課程,其經銷商和經銷商的汽車列表。

我的預測如下,但它不返回任何內容。

... 
    .setProjection(Projections.projectionList() 

    .add(Projections.property("friends.cars").as("cars") 
    ... 

回答

1

因爲你有課程的名單及訂車的,你可以簡單地獲取在單個查詢全圖:

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(); 
+0

感謝您的回答,請你看看我的問題在http://stackoverflow.com/questions/29980421/how-to-retireve-a-set-member-objects-using-hibernate – Jack

0

如果高performences是不是一個問題,那麼你應該讓Hibernate做他的工作。 只需使用你實體的獲取者。 對於爲例:

Student student1 = session.get(Student.class, 1L); 
List<Course> courses = student1.getCourses(); 
Dealer dealer = student1.getDealer(); 
Set<Car> cars = dealer.getCars(); 
+1

感謝但性能應該考慮。 – Jack

4
// Projection is not needed, Hibernate will load child values as shown below 

    Student student = session.get(Student.class); 
    List<Course> 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("b.r", "b.r", JoinType.INNER_JOIN); 
    criteria.createAlias("b.c", "b.c", 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)); 
+0

感謝您的答案,我有一個新的問題,併爲該問題發佈新問題,請看看謝謝,http://stackoverflow.com/questions/29980421/how-to-retireve-a-set-list-of-member-objects - 使用 - 休眠 – Jack

0

我不知道是否可以使用QueryOver但它會爲這些類型的任務非常簡單。

Student student = null; 
Dealer dealer = null; 
Course course = null; 
Car car = null; 

var myStudent = Session.QueryOver<Student>(() => 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<StudentModel>()) 
    .List<StudentModel>().AsQueryable(); 

創建一個StudentModel DTO以獲得結果。這只是一個提示,您可以根據您的要求進行修改。我希望這會起作用。 :)

相關問題