hibernate dao设计问题
我希望创建一个通用的 DAO 来处理我的休眠应用程序中的 CRUD。我的实体大多数关联为“懒惰获取”。但我发现为了让 hibernate 在 SELECT 方面尽可能高效,我必须在我的 DAO 上创建多个方法。我的意思是:
实体 A 有两个关联。有时我想在不加载关联的情况下检索该实体,有时我希望它完全填充,因此我在 DAO 上放置两种方法:
getWhatever()
getWhateverWithLoadedAssociations()
并且我有两个不同的查询,一个没有连接获取,另一个带有连接获取。结果是 hibernate 总是执行单个选择,无论它是否懒惰,因为我知道我想要预先得到什么。
这样做的问题是,在保存一两个 SELECT 的同时,由于方法的数量而增加了复杂性。
那么这样的做法是否太过极端了呢?我是否应该只使用 getWhatever() 并在需要关联数据时让 hibernate 执行另一个选择,即使我可以避免不执行该 SELECT?
我希望这不会太令人困惑。我正在尝试计算由于延迟加载而导致的 SELECT 数量的成本与代码复杂性的比较,
谢谢
Im looking to create a generic DAO to handle CRUD in my hibernate app. My entities have most associations as LAZY fetching. But I find in order to have hibernate be efficient as possible with the SELECTs I have to create multiple methods on my DAOs. Here's what I mean:
Entity A has two associations. Sometimes I want to retrieve this entity without loading the associations and sometimes I want it fully populated, so I'd put two methods on the DAO:
getWhatever()
getWhateverWithLoadedAssociations()
and I'd have two different queries, one without join fetch, and the other with join fetch. The result is hibernate always does a single select regardless if its LAZY or not, because I know what I want to get up front.
The problem with this is, while saving a SELECT or two, its adding complexity due to the number of methods.
So is this being to extreme? Should I just have getWhatever() and just let hibernate do another select when I need the data for the association, even though I could have saved from not doing that SELECT?
I hope this is not too confusing. I'm trying to figure out the cost of number of SELECTS due to lazy loading, vs. code complexity
thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
那么你的问题是你的方法可能太多了?我认为这是对的,因为这些方法做了不同的事情。
如果您想减少数量并且正在使用 HQL,您可以向方法添加一个参数,说明是否要加入获取关系:
其中 f 可以是布尔值,也可以是返回字符串的 HQL 片段的对象,该字符串为您提供要获取的关系。
或者
So your problem is that you may have too many methods? I thinks it's right, because those methods do different things.
If you want to reduce the number and you're using HQL you may add a parameter to the method that says if you want to join fetch the relations:
where f can be a boolean, or an object that returns the HQL fragment of string that gives you that relations to fetch.
or
我认为这可能属于过早优化。换句话说,除非您确定存在性能问题,否则不要这样做。
现在就让 Hibernate 进行延迟获取,如果应用程序太慢,您可以只在需要的地方添加这些方法。
I think this might qualify as premature optimization. In other words don't do it unless you know for sure there's a performance problem there.
Just let Hibernate do its lazy fetching for now, and if the app is too slow you can start adding these sort of methods only where they are needed.
如果您启用了惰性关联/获取,那么如果一段不需要关联的代码调用
getWhatever()
或getWhateverWithLoadedAssociations()
会有什么区别?它应该会产生相同数量的 SQL 查询。如果您只有一个
getWhatever()
方法,请检查可能性:无论哪种情况,仅在需要时才加载关联。
延迟加载的目的是让你不必担心这种类型的事情——如果调用 DAO 方法的代码访问了关联,那么它就会被加载;如果没有,那就不是。
If you have lazy associations/fetching enabled, then what is the difference if a piece of code that doesn't need the association calls
getWhatever()
orgetWhateverWithLoadedAssociations()
? It should result in the same number of SQL queries.Examine the possibilities if you have just a single
getWhatever()
method:In either case, the association is only loaded when needed.
The purpose of lazy loading is so you don't have to worry about this type of thing - if the code calling the DAO method accesses the association, then it is loaded; if not, it is not.
恕我直言,我将在通用 DAO 中添加以下一些方法:
IMHO, I will add some following methods into the generic DAO:
您可以有一个通用的(在基类中)dao 方法:
您调用 Hibernate.initialize(entity) 的地方;
You can have a common (in a base class) dao method:
Where you call
Hibernate.initialize(entity)
;在我看来,是的,你太极端了。
除非您正在开发包含数千个此类查询的批处理过程,否则执行单个查询与 hibernate 在延迟加载时执行的查询之间没有太大区别。
无论如何,如果您已经确认对应用程序性能的担忧,那么您刚才提出的做法并不是一个坏做法。
In my opinion, yes, you are being extreme.
Unless you are developing a batch procedure with thousends of these queries, there is not much difference between performing one single query and the queries that hibernate does when loading lazyly.
Anyway, if you have confirmed worries about performance in your application, it is not a bad practice what you just proposed.