2013-07-01 7 views
0

Я использую структуру запросов критериев спящего режима для создания отчетов. Я также должен сортировать и фильтровать. Все отлично работало, когда данные были ограничены одним объектом. Однако у меня есть требование объединить несколько объектов и показать результат в одной таблице. Ниже приводятся следующие объекты:Entity для объединения нескольких таблиц

@Entity 
@Table(name = "user_profile") 
@Where(clause = "deleted = 0") 
public class UserProfile { 

    @GeneratedValue(strategy = GenerationType.AUTO) 
    Long id; 

    @Column(name = "username") 
    private String username; 

    @Column(name = "email") 
    private String email; 

    @Column(name = "first_name") 
    private String firstName; 

    @Column(name = "middle_name") 
    private String middleName; 

    @Column(name = "last_name") 
    private String lastName;   
} 

@Entity 
@Table(name = "user_data") 
public class UserData { 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 

    @Column(name = "username") 
    private String username; 

    @Column(name = "password") 
    private String password; 

    @Column(name = "account_nonexpired") 
    private Boolean accountNonExpired = true; 

    @Column(name = "account_nonlocked") 
    private Boolean accountNonLocked = true; 

    @Column(name = "credentials_nonexpired") 
    private Boolean credentialsNonExpired = true; 

    @Column(name = "enabled") 
    private Boolean enabled = false; 
} 

@Entity 
@Table(name = "user_role") 
public class Role { 
    private static final long serialVersionUID = 1L; 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 

    @Column(name = "username") 
    private String username; 

    @Column(name = "role") 
    private String role; 
} 

Эти объекты имеют общее имя пользователя. Возможно ли создать объект, который не имеет таблицы, но просто содержит эти объекты в качестве полей? Например:

public Class UserDataProfileRoleMapping{ 
    private UserProfile userProfile; 
    private List<Role> role; 
    private UserData userData; 
} 

Я могу создать таблицу сопоставлений, но я сохранил ее как последнее средство.

Редактировать

Запрос, который я хочу стрелять что-то вроде:

select * from user_data u, user_role r, user_profile up 
where 
u.username = r.username and 
r.username = up.username; 
+0

ли Вы только должны агрегированный/присоединились информацию для отображения или вы действительно нужен стол со всей этой информацией ? Если это первый случай, вы можете создать DTO с необходимой информацией и создать соответствующий запрос. –

+0

Мне нужно собрать эту информацию. Тем не менее, я также хочу использовать запрос критериев hibernate для api. Создание DTO приведет к обработке сортировки, фильтрации и разбивки на страницы вручную. – Vaibhav

+0

Нет, DTO - это просто ПОЖО, которое будет содержать только нужные вам данные/столбцы. В ответ я создам быстрый пример. –

ответ

2

Вы должны создать POJO как DTO, который будет содержать именно ту информацию, вам нужно, и использовать его вместо фактические сущности. Давайте предположим, что у нас есть три сущности, Order, OrderItem и Customer и запрос должен быть чем-то вроде

SELECT Order.orderDate, Customer.name, OrderItem.amount 
FROM Order 
JOIN Customer ON Order.customerId = Customer.id 
JOIN OrderItem ON Order.id = OrderItem.orderId 
WHERE OrderItem.name = 'Puppet'; 

Теперь DTO бы:

public class ReturnDto { 
    private Date date; 
    private String customerName; 
    private int amount; 

    public ReturnDto(Date date, String customerName, int amount) { 
     this.date = date; 
     ... 
    } 

    // getters for the three properties 
} 

И в вашем DAO вы могли бы сделать что-то по следующие строки:

CriteriaBuilder cb = getEntityManager().getCriteriaBuilder(); 
CriteriaQuery<ReturnDto> cQuery = cb.createQuery(ReturnDto.class); 

Root<Order> orderRoot = cQuery.from(Order.class); 
Join<Order, Customer> customerJoin = orderRoot.join(Order_.customer); 
Join<Order, OrderItem> orderItemJoin = orderRoot.join(Order_.orderItems); 

List<Predicate> criteria = new ArrayList<Predicate>(); 

criteria.add(cb.equal(orderItemJoin.get(OrderItem_.name), "Puppet"); 

// here you can do the sorting, e.g. - all with the criteria API! 
cQuery.orderBy(...); 
cQuery.distinct(true); 

cQuery.select(cb.construct(ReturnDto.class, 
    orderRoot.get(Order_.date), 
    customerJoin.get(Customer_.name), 
    orderItemJoin.get(OrderItem_.amount) 
)); 

cQuery.where(cb.and(criteria.toArray(new Predicate[criteria.size()]))); 
List<ReturnDto> returnList = entityManager.createQuery(cQuery).getResultList(); 

Очевидно, что вы не можете сохранить элементы в возвращенном списке, но вы получите точно информацию вы хотите, и вы все еще можете обрабатывать вещи со списком, с которым вы не можете справиться с API SQL/Criteria.

Update: Просто найти эту ссылку, которая также может помочь с концепцией я использовал выше: http://www.javacodegeeks.com/2013/04/jpa-2-0-criteria-query-with-hibernate.html?utm_content=buffer0bd84&utm_source=buffer&utm_medium=twitter&utm_campaign=Buffer

Смежные вопросы