在 Hibernate 中检索图结构

发布于 2024-10-14 16:35:22 字数 473 浏览 4 评论 0原文

对象结构就像这样

  • Invoice
    • 客户
    • 日期
    • 数量
    • 有很多产品线(产品、数量、价格)
    • 有很多服务线(服务、数量、价格)
    • 有多种付款选项(付款类型(支票、收据等)、日期、总和)

如果我需要检索使用 Hibernate 可以很容易地通过延迟加载来完成给定时期的发票列表,而无需编写任何代码,只需调用 get...但是存在太多数据库调用的缺点,因此在多用户环境中,此解决方案是不行的。

通过普通 JDBC,我使用 3 个查询解决了这个问题:发票和 ProductLines、发票和 ServiceLines 以及发票和付款选项之间的 3 个联接。之后我在内存中构造了该对象。

我知道 Hibernate 也可以做到这一点,但我的问题是没有负载图之类的东西,所以我可以传递发票列表并以最少的调用次数(最佳的) 检索数据?

Object structure is like this

  • Invoice
    • Customer
    • Date
    • Number
    • has many ProductLines (Product ,Quantity ,Price)
    • has many ServiceLines (Service , Quantity,Price)
    • has many PaymentOptions (PaymentType(Check,Receipt,etc.),Date,Sum)

If I need to retrieve a list of invoices for a given period with Hibernate is very easy to do with lazy loading without writing any code just call get...BUT there is the drawback of too many DB calls, so in a multiuser environment this solution is not ok.

With plain JDBC I solved this using 3 queries : 3 joins between Invoice and ProductLines, Invoice and ServiceLines and Invoice and Payment Options. After that I constructed the object in the memory.

Same can be done with Hibernate I know BUT my question is there is no such thing as load graph or so I can pass a list of invoices and in minimum number of calls (optimum one)
to retrieve the data ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

jJeQQOZ5 2024-10-21 16:35:22

您可以使用带有连接获取的查询将整个对象图放入内存:

Query query = entityManager.createQuery("select distinct invoice from Invoice as invoice " 
            + "left join fetch invoice.productLines "                
            + "left join fetch invoice.serviceLines "
            + "left join fetch invoice.paymentOptions");
for (Object object : query.getResultList()) {
    // Code here
}

You can use queries with join fetching to get the entire object graph into memory:

Query query = entityManager.createQuery("select distinct invoice from Invoice as invoice " 
            + "left join fetch invoice.productLines "                
            + "left join fetch invoice.serviceLines "
            + "left join fetch invoice.paymentOptions");
for (Object object : query.getResultList()) {
    // Code here
}
复古式 2024-10-21 16:35:22

您可能想考虑 batch获取发票行以及急切获取多对一关联(例如客户)。

这不会让您减少到一次数据库调用,但如果您将批量大小调整为稍微超过发票中每种类型的平均行数,那么您可以减少到每种行类型一次。

您还可以使用 JPQL / HQL 进行查询并显式获取连接行 (正如 Russ 描述的),但与批量获取方法相比,您会得到更大的结果集:

Query query = entityManager.createQuery("select distinct invoice from Invoice as invoice " 
            + "left join fetch invoice.productLines "                
            + "left join fetch invoice.serviceLines "
            + "left join fetch invoice.paymentOptions");
for (Object object : query.getResultList()) {
    // Code here
}

如果传输的原始数据的大小被证明太高,您可以通过删除“fetch”来显式禁用获取在相关地方查询。

请注意,使用 JPQL 存在维护问题,因为编译器无法为您检查所有属性名称,并且如果所有关联的获取都关闭,则查询是净成本。如果性能不是迫在眉睫的问题,您可能希望从批量获取开始。

You may like to consider batch fetching for your invoice lines and eager fetching for many to one associations such as Customer.

This will not get you down to one DB call, but if you tune your batch sizes to slightly exceed the average number of lines of each type in an invoice, then you could get down to one per line type.

You could also query using JPQL / HQL and explicitly fetch-join the lines (as Russ decribes), but you get a larger result set than you would with a batch fetching approach:

Query query = entityManager.createQuery("select distinct invoice from Invoice as invoice " 
            + "left join fetch invoice.productLines "                
            + "left join fetch invoice.serviceLines "
            + "left join fetch invoice.paymentOptions");
for (Object object : query.getResultList()) {
    // Code here
}

If the size of the raw data transferred proves to be too high, you can disable fetching explicitly by removing "fetch" from the query in the relevant places.

Note that there is a maintenance issue using JPQL because the compiler cannot check all the property names for you, and if fetching is off for all associations then the query is a net cost. You may like to start with batch fetching if performance is not an immediate issue.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文