2012-09-05 5 views
5

Mam problem w moim projekcie. Próbuję utworzyć funkcję wyszukiwania w celu przeszukiwania użytkowników z poziomu tabeli użytkownika, ale w międzyczasie chcę również pobrać odpowiadający "awatar użytkownika" z innej tablicy z Avatarem "url". Chcę utworzyć twarde mapowanie między tymi dwoma tabelami. Jak mogę to zrobić elastycznie przy użyciu Kryteriów Hibernacji? Obie tabele używają klucza podstawowego "loginID".Używanie kryteriów hibernacji do pobierania danych z wielu tabel bez ustawienia odwzorowania encji

Mam dwie klasy:

public class User{ 
    private String loginID; 
    private String screenname; 
    ...... 
} 
public class Avatar{ 
    private Integer id; 
    private String loginID; 
    private String url; 
    ....... 
} 

Co mam napisane:

public List<Users> searchLogin(String keywords, int startFrom) { 
     List<Users> userList = new ArrayList<Users>(); 
     try { 
      Session session = HibernateUtil.beginTransaction(); 
      Criteria criteria = session.createCriteria(Users.class,"users"); 
      criteria.add(Restrictions.ilike("loginID", keywords, MatchMode.ANYWHERE)); 
      userList = criteria.list(); 
      if (session.isOpen()) { 
       session.close(); 
      } 
      return userList; 
     } catch (Exception e) { 
      e.printStackTrace(); 
      return null; 
     } 
    } 

Dzięki chłopaki !!

Odpowiedz

3

Zastosowanie HQL

from User u,Avatar a where where u.loginID = a.loginID and u.loginID = :loginID 

ta zwróci listę [user] Awatar tablic.

+3

dzięki za odpowiedź. Czy mogę użyć Kryteriów, aby to zrobić? – leon

2

Obie tabele używają klucza podstawowego "loginID".

Czy to prawda? Widzę, że klasa Avatar mająca pole o nazwie "id", czy nie jest to identyfikator/klucz podstawowy?

Zauważyłem również, że odsyłasz od Avatar do User, używając pola loginId. Prawidłowy sposób łączenia podmiotów jest według ich klasy. Używanie adnotacji powinna wyglądać następująco:

@Entity 
public class User 
{ 
    @Id 
    private String loginId; 
    private String screenName; 
    @OneToOne(mappedBy = "user") 
    private Avatar avatar; 
} 

@Entity 
public class Avatar 
{ 
    @Id 
    private Integer id; 
    @OneToOne 
    private User user; 
    private String url; 
} 

Jeśli następnie chce sprowadzić User i URL Avatar należącego do User najlepszą rzeczą, jaką możesz zrobić, to przynieść User i to Avatar za pomocą sprzężenia i następnie uzyskaj dostęp do adresu URL Avatar, a tym samym nie musisz przesyłać z Object do User ani Avatar zachowując bezpieczeństwo typu.

User user = fetchUserJoinAvatar("123"); 
String url = user.getAvatar().getUrl(); 

public User fetchUserJoinAvatar(String loginId) 
{ 
    CriteriaBuilder cb = em.getCriteriaBuilder(); 
    CriteriaQuery<User> query = cb.createQuery(User.class); 

    Root<User> user = query.from(User.class); 
    user.fetch("avatar"); 
    query.select(user).where(cb.equal(user.get("loginId"), loginId)); 
    return em.createQuery(query).getSingleResult(); 
} 
+0

Imho to powinna być zaakceptowana odpowiedź. – displayname

6

Późno, ale może być przydatne dla innych osób, które faktycznie google i kończy się tutaj. Nie trzeba mapować ani używać HQL.

Oto jak:

CriteriaBuilder builder = em.getCriteriaBuilder(); 
    CriteriaQuery<Tuple> criteria = builder.createTupleQuery(); 
    Root<EntityA> entityARoot= criteria.from(EntityA.class); 
    Root<EntityB> entityBRoot = criteria.from(EntityB.class); 

    //Predicates 
    List<Predicate> predicates = new ArrayList<>(); 
    //Add the predicates you need 

    //And predicates 
    List<Predicate> andPredicates = new ArrayList<>(); 
    andPredicates.add(builder.equal(entityARoot.get("id"), entityBRoot.get("id"))); 
    andPredicates.add(builder.and(predicates.toArray(new Predicate[0]))); 

    criteria.multiselect(entityARoot, entityBRoot); 
    criteria.where(andPredicates.toArray(new Predicate[0])); 

    TypedQuery<Tuple> query = em.createQuery(criteria); 

    List<Tuple> result = query.getResultList(); 
Powiązane problemy