可以延迟批量加载实例字段,同时保持紧密耦合吗?
假设我有以下类:
public class Foo {
public Bar bar;
}
一个巨大的 iBATIS 查询加载 Foo 的许多实例并填充数据库中的所有 bar
字段。我想将巨大的查询分成两个:
- 一个查询加载许多
Foo
实例,将bar
字段保留为空。 - 另一个查询加载一些关联的
Foo
实例的所有bar
字段。
这个想法是,第一个查询将首先执行,然后仅在稍后需要时才执行第二个查询。
诀窍在于关联。我可以批量加载 bar
字段,但是将该数据注入回关联的 Foo
的最佳方法是什么?有没有办法让每个延迟加载的实例字段执行一个查询?这似乎会抵消 iBATIS 的性能优势。
Suppose I have the following class:
public class Foo {
public Bar bar;
}
One giant iBATIS query loads many instances of Foo and populates all of the bar
fields from a database. I would like to split up the giant query into two:
- One query to load many
Foo
instances, leaving thebar
fields null. - Another query to load all of the
bar
fields for some associatedFoo
instances.
The idea is that the first query would be executed initially, then the second would be executed only if needed later on.
The trick is the association. I can batch load bar
fields, but what's the best way to inject that data back into the associated Foo
s? Is there any way around having one query executed per lazily-loaded instance field? This seems like it would counteract the performance benefits of iBATIS.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
尽管从数据库加载对象图很诱人,但我们通常会尽量避免这种情况,因为这意味着每个成员一次查询,并且在获取大型集合时,可能会导致对数据库进行很多很多查询和很长的响应时间。
因此我们通常采用成员分离的方式来建模。假设您有一个有用户的商店。您不是将用户建模为商店中的列表,而是使用读取“List getUsersForShop(shop)”的 DAO 调用。
我们的一些页面甚至更进一步。对于分页网页,从数据库获取所有对象是没有用的,因为它们不会同时显示。因此,我们进一步将其拆分:
列出 getUserIdsForShop(shop)
,然后对于页面上的每一行,我们执行“User getUserForId(long id)”。
这将导致服务器、数据库和客户端之间的数据流最小化,并将减少每页的调用次数。如果您的搜索结果是 10.000 个用户,但每页只显示 10 个用户,那么您刚刚保存了 99990 个用户的获取,并将它们保存在内存中。
不要用它作为锤子来钉所有的指甲。这只是大型对象图需要考虑的一个选项。
Although it is tempting to load object graphs from the database, we usually try to avoid that because it means one query per member, and when fetching large sets, can result in many, many queries on the database and long response times.
Therefore we usually model it in such a way that the member is seperated. Let's say you have a Shop with Users. Instead of modelling the Users as a list in your shop, you have a DAO call which reads "List getUsersForShop(shop)".
Some of our pages go even furter. For paginated web pages, there's no use to get all objects from the database, since they're not displayed at the same time. So we split it even further:
List getUserIdsForShop(shop)
and then for each row on the page, we do "User getUserForId(long id)".
This will result in minimal dataflow between the server, the database and the client, and will reduce the number of calls per page. If your search result is 10.000 users, but you only display 10 per page, you've just saved the fetching of 99990 users, and holding them in memory.
Don't use this as a hammer for all your nails. It's just an option to consider for large object graphs.