我正在使用hibernate条件查询框架来生成报告。我也必须提供排序和过滤。当数据仅限于一个实体时,事情进展顺利。但是,我需要加入多个实体并在单个表中显示结果。以下是实体:
@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 :(得分:3)
您应该创建一个POJ作为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();
显然,您无法将项目保存在返回的列表中,但是您可以获得所需的信息,并且您仍然可以使用列表处理事务,而使用SQL / Criteria API无法处理这些信息。
更新:刚刚找到此链接,这也可能有助于我上面使用的概念: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