Java 冬眠n+;1期
我有以下课程: 订单:Java 冬眠n+;1期,java,hibernate,hibernate-criteria,Java,Hibernate,Hibernate Criteria,我有以下课程: 订单: @Table(name = "ORDERS") public class Order { @Id @Column(name = "order_id") @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(name = "user_id", nullable = false) private Long userId;
@Table(name = "ORDERS")
public class Order {
@Id
@Column(name = "order_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "user_id", nullable = false)
private Long userId;
@JsonManagedReference
@OneToMany(mappedBy = "order", fetch = FetchType.EAGER)
private Set<OrderDetail> orderDetails;
@JsonManagedReference(value = "order-note")
@OneToMany(mappedBy = "order", fetch = FetchType.EAGER)
private Set<Note> notes;
}
@Table(name = "ORDER_SIZES")
public class OrderSize {
@Id
@Column(name = "order_size_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@JsonBackReference
@ManyToOne
@JoinColumn(name = "order_detail_id")
private OrderDetail orderDetail;
}
注释
@Table(name = "ORDER_DETAILS")
public class OrderDetail {
@Id
@Column(name = "order_detail_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@JsonBackReference
@ManyToOne
@JoinColumn(name = "order_id")
private Order order;
@JsonManagedReference
@OneToMany(mappedBy = "orderDetail", fetch = FetchType.EAGER)
private Set<OrderSize> orderSizes;
@JsonManagedReference(value="order-detail-note")
@OneToMany(mappedBy = "orderDetail", fetch = FetchType.EAGER)
private Set<Note> notes;
}
@Table(name = "NOTES")
public class Note {
@Id
@Column(name = "note_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@JsonBackReference(value="order-note")
@ManyToOne
@JoinColumn(name = "order_id", nullable = true)
private Order order;
@JsonBackReference(value="order-detail-note")
@ManyToOne
@JoinColumn(name = "order_detail_id", nullable = true)
private OrderDetail orderDetail;
}
我想执行一个查询(使用Hibernate的条件),并获取所有订单及其关联的详细信息、大小和注释
public List<Order> findByUser(Long userId) {
Criteria criteria = createEntityCriteria();
criteria.add(Restrictions.eq("userId", userId));
return (List<Order>) criteria.list();
}
我无法想出一个解决方案,只需一次查询即可获得所需的所有信息。插入以下内容后:
- 2附注实体
- 2个OrderDetail实体(每个包含2个Note实体)
- 1个订单实体(包含2个OrderDetail实体和2个Note实体)
@OneToMany(mappedBy = "order", fetch = FetchType.EAGER)
@Fetch(FetchMode.JOIN)
private Set<OrderDetail> orderDetails = new HashSet<>();
@OneToMany(mappedBy = "order", fetch = FetchType.EAGER)
@Fetch(FetchMode.JOIN)
private Set<Note> notes;
但是,如果您仍然面临将数据作为一个查询获取的困难,我建议使用QueryDSL[1],这里有示例和maven设置细节[2]
LE:
如何在QueryDSL中创建查询的示例如下:
public List<Order> findByUserQueryDsl(Long userId) {
System.out.println("Finding by User ID query dsl");
EntityManager em = this.entityManagerFactory.createEntityManager();
return new JPAQuery<>(em, HQLTemplates.DEFAULT)
.select(QOrder.order)
.from(QOrder.order)
.leftJoin(QOrder.order.notes).fetchJoin()
.leftJoin(QOrder.order.orderDetails, QOrderDetail.orderDetail).fetchJoin()
.leftJoin(QOrderDetail.orderDetail.notes).fetchJoin()
.where(QOrder.order.userId.eq(userId))
.fetch();
}
[1]
[2] 您是否考虑过使用@Fetch@Chris作为第一个参数传递什么?criteria.setFetchMode(“foo”,FetchMode.JOIN)我指的是导致n+1查询的实体关系,也用@Fetch(FetchMode.JOIN)注释它。我会给你一个更完整的答案,但你可以在这段时间内试试。@Chris谢谢你,这似乎并不能解决问题。我得到了相同的n个查询。
Hibernate:
select
this_.order_id as order_id1_3_4_,
this_.user_id as user_id2_3_4_,
notes2_.order_id as order_id2_0_6_,
notes2_.note_id as note_id1_0_6_,
notes2_.note_id as note_id1_0_0_,
notes2_.order_id as order_id2_0_0_,
notes2_.order_detail_id as order_de3_0_0_,
orderdetai3_.order_detail_id as order_de1_1_1_,
orderdetai3_.order_id as order_id2_1_1_,
order4_.order_id as order_id1_3_2_,
order4_.user_id as user_id2_3_2_,
ordersizes5_.order_detail_id as order_de2_2_7_,
ordersizes5_.order_size_id as order_si1_2_7_,
ordersizes5_.order_size_id as order_si1_2_3_,
ordersizes5_.order_detail_id as order_de2_2_3_
from
orders this_
left outer join
notes notes2_
on this_.order_id=notes2_.order_id
left outer join
order_details orderdetai3_
on notes2_.order_detail_id=orderdetai3_.order_detail_id
left outer join
orders order4_
on orderdetai3_.order_id=order4_.order_id
left outer join
order_sizes ordersizes5_
on orderdetai3_.order_detail_id=ordersizes5_.order_detail_id
where
this_.user_id=?
Hibernate:
select
orderdetai0_.order_id as order_id2_1_0_,
orderdetai0_.order_detail_id as order_de1_1_0_,
orderdetai0_.order_detail_id as order_de1_1_1_,
orderdetai0_.order_id as order_id2_1_1_
from
order_details orderdetai0_
where
orderdetai0_.order_id=?
public List<Order> findByUserQueryDsl(Long userId) {
System.out.println("Finding by User ID query dsl");
EntityManager em = this.entityManagerFactory.createEntityManager();
return new JPAQuery<>(em, HQLTemplates.DEFAULT)
.select(QOrder.order)
.from(QOrder.order)
.leftJoin(QOrder.order.notes).fetchJoin()
.leftJoin(QOrder.order.orderDetails, QOrderDetail.orderDetail).fetchJoin()
.leftJoin(QOrderDetail.orderDetail.notes).fetchJoin()
.where(QOrder.order.userId.eq(userId))
.fetch();
}
select
order0_.order_id as order_id1_3_0_,
notes1_.note_id as note_id1_0_1_,
orderdetai2_.order_detail_id as order_de1_1_2_,
notes3_.note_id as note_id1_0_3_,
order0_.user_id as user_id2_3_0_,
notes1_.order_id as order_id2_0_1_,
notes1_.order_detail_id as order_de3_0_1_,
notes1_.order_id as order_id2_0_0__,
notes1_.note_id as note_id1_0_0__,
orderdetai2_.order_id as order_id2_1_2_,
orderdetai2_.order_id as order_id2_1_1__,
orderdetai2_.order_detail_id as order_de1_1_1__,
notes3_.order_id as order_id2_0_3_,
notes3_.order_detail_id as order_de3_0_3_,
notes3_.order_detail_id as order_de3_0_2__,
notes3_.note_id as note_id1_0_2__
from
orders order0_
left outer join
notes notes1_
on order0_.order_id=notes1_.order_id
left outer join
order_details orderdetai2_
on order0_.order_id=orderdetai2_.order_id
left outer join
notes notes3_
on orderdetai2_.order_detail_id=notes3_.order_detail_id
where
order0_.user_id=?