2012-03-05 80 views
0

我有兩個實體有選擇和的毗連

@Entity 
@Table(name = "users") 
public class User extends Model { 
    public String name; 

    @ManyToMany 
    public List<Role> roles; 
} 

而且

@Entity 
@Table(name = "roles") 
public class Role extends Model { 
    public String name; 
} 

表JPA JPQL請求包含

Table Users |  | Table Roles |   |Table Users_roles | 
id | Name |  | id | Name |   |users_id | roles_id | 
1  | User 1 |  | 1  | CEO  |   | 2  | 1  | 
2  | User 2 |  | 2  | Manager |   | 2  | 2  | 
3  | User 3 |          | 3  | 1  | 

我要讓下面的查詢(OK在PostgreSQL 9.1 .12)

SELECT u.*, array_to_string(array_agg(r.name ORDER BY r.name ASC), '/') 
    FROM users u 
    LEFT OUTER JOIN users_roles ur ON u.id=ur.users_id 
    FULL JOIN roles r ON r.id=ur.roles_id 
    GROUP BY u.id, ur.users_id 
    ORDER BY array_to_string ASC 

我有結果我想

User name | roles 
User 1 |   
User 3 | CEO   
User 2 | CEO/MANAGER   

你能幫助我獲得此請求的JPA語法?

回答

1

無法直接使用JPQL查詢來做到這一點。但是,你可能只是在它返回角色名稱的字符串用戶實體的方法,並與他們的角色獲取用戶:

List<User> users = em.createQuery("select u from User u left join fetch u.roles") 
        .getResultList(); 

,並利用番石榴的木匠,在User.java:

public String getUserNames() { 
    List<String> roleNames = new ArrayList<String>(); 
    for (Role role : roles) { 
     roleNames.add(role.getName(); 
    } 
    return Joiner.on("/").join(roleNames); 
} 
0

如果您只是想要數據,那麼只需使用本機SQL查詢來執行您擁有的SQL。

如果你想要對象,那麼只需選擇User對象並訪問它們在Java中的角色來收集數據。要優化對角色的查詢,您可以加入獲取或批量獲取它。

0

我可以通過做這個請求:

String jpql = "SELECT u.*," + 
    " array_to_string(array_agg(r.name ORDER BY r.name ASC), '/ ')" + 
    " FROM users u" + 
    " LEFT OUTER JOIN users_roles ur ON u.id=ur.users_id" + 
    " FULL JOIN roles r ON r.id=ur.roles_id" + 
    " GROUP BY u.id, ur.users_id" + 
    " ORDER BY array_to_string DESC" ; 

Query query = Model.em().createNativeQuery(jpql); 
scManager.bindParameters(query); 

List<Object[]> searchCriteriaUsers = new JPAQuery(jpql, query).fetch(); 

請求成功和結果。但我正在尋找JPQL查詢來按角色名稱排序列表...