您的位置:jsp学习站首页 >> 框架/开源 >> Hibernate >> Designing "query by criteria"(hibernate 2.1)

Designing "query by criteria"(hibernate 2.1) (1)

[ 来源:互网络 | 更新日期:2007-09-02 01:58:09 | 浏览次数:10571]
简介:Dec 2003, 14:47by gavin@hibernate
Designing "query by criteria" 01. Dec 2003, 14:47
by gavin@hibernate.org | Link | 16 comments
One of the great improvements in Hibernate 2.1 is that we finally have a mature Criteria query API. For a very long time I let this feature languish because I just wasn´t sure what it should really look like. Every QBC API I´ve looked at is designed differently and there is certainly nothing like a standard API to learn from. I´ve seen everything from this:

new Criteria(Project.class)
.addEq("name", "Hibernate")
.addLike("description", "%ORM%")
.execute();


to this:

Criteria crit = new Criteria(Project.class)
crit.getProperty("name").eq("Hibernate);
crit.getProperty("description).like("%ORM%");
crit.execute();


I don´t like either of these approaches because the addition of new types of criterion requires the uncontrolled growth of a single central interface (Criteria, in the first case; Property in the second).

I like the second approach even less because it is very difficult to chain method calls. What should the eq() method return? Well, it seems most reasonable that it would return the receiving object (ie. the property). But it is very unusual to apply multiple criteria to the same property! So we would really prefer it to return the Criteria if we wanted to chain method calls. Well, I don´t know about you, but I think that any API that returned the receiver from two calls ago might not be considered "intuitive". So we are stuck with that evil temp variable.

I´d seriously consider improving this second approach to look like this:

new Criteria(Project.class)
.getProperty("name").eq("Hibernate)
.and()
.getProperty("description).like("%ORM%");
.execute();



Which is actually very clean. Unfortunately, the interfaces themselves are quite bizzare: and() is an operation defined by .... Criterion? The and() method returns .... the Criteria? This doesn´t feel like a very natural OO design. And I think it would confuse new users. I´ll come back to another reason why "and" and "or" should not be operations at all.

As a variation upon the first approach, I have seen the following:

new Criteria(Project.class)
.add( new Equals("name", "Hibernate") )
.add( new Like("description", "%ORM%") )
.execute();


This avoids the problem of the Criteria interface growing out of control. But I hate Java constructors almost as much as I hate temp variables! The problem with constructors in Java is that they cannot be given meaningful names. We can´t call a constructor EqualsIgnoreCase() if the class is named Equals. Secondly, once we start using constructors, we pretty much permanently nail down the Criterion class hierarchy. We tie client code directly to the concrete classes. I can´t change my mind later and decide that Equals and EqualsIgnoreCase shou
[1] [2] [3]
Tags:关键字:Designing "query by criteria"(hibernate 2.1)
责任编辑:glen