我使用EJB应用程序在我的J2EE中有一个3层模型:Cart,它有许多LineItems,每个都有很多书(Book不一定是指一个Line Item,它不是双向的)。
Cart(1) <--> (M) LineItem (1) --> (M) Book
我希望所有人都渴望加载,即当我提取购物车时,它还应加载所有行项目和所有这些书籍,只需最少的SQL查询(我使用关系数据库,例如MySQL )。它可以使用3个查询完成,每个查询对应一种类型。设置&#34; FetchType.EAGER&#34;导致所有对象被加载,但它有&#34; 2 + n&#34;调用:1对购物车的查询(显然),对行项目的另一个查询,但后来不得不对书籍进行n次查询,其中n是行项目的数量。
我曾经使用Ruby on Rails,使用eager load(使用includes)可以满足我的需要。我也可以用J2EE吗?
(注意:加入可能是一个选项,但我希望从查询中自动填充实体,尽管我认为连接不太舒服)。
我的代码示例:
@Entity
public class Cart implements Serializable {
@OneToMany(cascade=ALL, mappedBy="cart", fetch = FetchType.EAGER)
private List<LineItem> lineItems;
}
@Entity
public class LineItem implements Serializable {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="cart_id", referencedColumnName = "id")
private Cart cart;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name="book_id", referencedColumnName = "id")
private Book book;
}
@Entity
public class Book implements Serializable {
...
}
以下是购物车有3个行项目的SQL查询示例:
SELECT id, name FROM carts WHERE (id = 19)
SELECT id, quantity, book_id, cart_id FROM line_items WHERE (cart_id = 19)
SELECT id, description, name, price FROM books WHERE (id = 4)
SELECT id, description, name, price FROM books WHERE (id = 3)
SELECT id, description, name, price FROM books WHERE (id = 1)
答案 0 :(得分:1)
标准JPA提供了join fetch,它标记了一个急切获取的关系,就好像它是通过注释标记的那样。在您的情况下,只需要join fetch
lineItems
,因为book
会在单个查询中急切地加载每个LineItem
。
使用JPA 2.1,您可以使用Entity graph - 您不需要修改查询,只需在查询中附加一个描述符,用于定义应该急切获取哪些关系。
如果要优化可能的最小查询量,可能需要使用某些JPa提供程序中提供的batch fetching。但要注意,没有标准化的方法来启用它 - 我只是链接到如何使用EclipseLink。