2012-09-05 3 views
5

내 프로젝트에 문제가 있습니다. 그 동안 사용자 테이블에서 사용자를 검색 할 수있는 검색 기능을 만들려고했지만 그동안 다른 아바타 테이블에서 사용자의 아바타에 해당하는 "url"을 검색하려고합니다. 이 두 테이블간에 하드 매핑을 만들고 싶습니다. Hibernate Criteria를 어떻게 유연하게 사용할 수 있습니까? 두 테이블 모두 기본 키 "loginID"을 사용하고 있습니다.Hibernate 기준을 사용하여 엔티티 매핑 설정없이 여러 테이블에서 데이터 검색

내가 쓴 무엇
public class User{ 
    private String loginID; 
    private String screenname; 
    ...... 
} 
public class Avatar{ 
    private Integer id; 
    private String loginID; 
    private String url; 
    ....... 
} 

:

나는 두 개의 클래스가

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; 
     } 
    } 

감사들!

답변

3

사용 HQL은

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

이 [사용자, 아바타] 배열의 목록을 반환합니다.

+3

감사합니다. 기준을 사용하여이를 수행 할 수 있습니까? – leon

2

두 테이블 모두 "loginID"의 기본 키를 사용하고 있습니다.

이 정보가 맞습니까? Avatar 'id'라는 필드가있는 클래스가 있는데, id/primary 키가 아닙니까?

필드를 사용하여 Avatar에서 User 사이의 값을 나타 냈습니다. 엔티티를 연결하는 올바른 방법은 클래스에 따라 다릅니다. 당신이 그 다음이다 User을 페치 UserUser 당신이 할 수있는 최선의 일은에 속하는 Avatar의 URL을 가져 오기하려면

@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; 
} 

그것은 Avatar이 조인을 사용하여이고 : 주석을 사용하여이 다음과 같아야합니다 Avatar의 URL에 액세스하여 Object에서 UserAvatar 유형 안전을 유지할 필요가 없습니다.

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 이것이 허용 된 대답이어야합니다. – displayname

6

늦어 지지만 실제로 Google을 끝내고 여기서 끝나는 다른 사람들에게 유용 할 수 있습니다. HQL을 매핑하거나 사용할 필요가 없습니다.

는 방법은 다음과 같습니다 답장을 보내

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(); 
관련 문제