??xml version="1.0" encoding="utf-8" standalone="yes"?> Q?Q编写一个复合主键的cCustomerPKQ代码如下?/p>
CustomerPK.java import java.io.Serializable; public class CustomerPK implements Serializable { public CustomerPK() { } public CustomerPK(String name, String email) { this.name = name; this.email = email; } private String email; public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public int hashCode() { final int PRIME = 31; int result = 1; result = PRIME * result + ((email == null) ? 0 : email.hashCode()); result = PRIME * result + ((name == null) ? 0 : name.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; final CustomerPK other = (CustomerPK) obj; if (email == null) { if (other.email != null) return false; } else if (!email.equals(other.email)) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } } 作ؓW合主键c,要满以下几点要求?/p>
l 必须实现Serializable接口?/p>
l 必须有默认的public无参数的构造方法?/p>
l 必须覆盖equals和hashCodeҎ。equalsҎ用于判断两个对象是否相同QEntityManger通过findҎ来查找EntityӞ是根据equals的返回值来判断的。本例中Q只有对象的name和email值完全相同时或同一个对象时则返回trueQ否则返回false。hashCodeҎq回当前对象的哈希码Q生成的hashCode相同的概率越越好,法可以q行优化?/p>
Q?Q通过@IdClass注释在实体中标注复合主键Q实体代码如下?/p>
@Entity @Table(name = "customer") @IdClass(CustomerPK.class) public class CustomerEO implements java.io.Serializable { private Integer id; public Integer getId() { return this.id; } public void setId(Integer id) { this.id = id; } private String name; @Id public String getName() { return this.name; } public void setName(String name) { this.name = name; } private String email; @Id public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } } 标注复合主键旉要注意以下几个问题?/p>
l @IdClass标注用于标注实体所使用主键规则的类。它的定义如下所C?/p>
@Target({TYPE}) @Retention(RUNTIME) public @interface IdClass { Class value(); } 属性Class表示W合主键所使用的类Q本例中使用CustomerPKq个复合主键cR?/p>
l 在实体中同时标注主键的属性。本例中在email和name的getterҎ前标注@IdQ表C符合主键用这两个属性?/p>
Q?Q这样定义实体的复合主键后,通过以下代码便可以获得指定的实体对象Q?/p>
CustomerPK cpk = new CustomerPK("Janet","janetvsfei@yahoo.com.cn"); CustomerEO instance = entityManager.find(CustomerEO.class, cpk); 本文来自CSDN博客Q{载请标明出处Qhttp://blog.csdn.net/EJB_JPA/archive/2008/05/09/2422540.aspx
]]>
然后会出现新建项目的对话框如图所C?br />
然后点击Modify按钮后如?br />
java persistence选中Q这样就为项目增加了JPA的特性,其它Ҏ根据项目需要自行修攏V点击OK后。点dơNEXTQ忽略的几步Ҏ自n情况而定Q到JPA FACETH口Q如下图Q?br />
因ؓ׃用的是hibernate列表中没有所以platform选择Generic,Type选择disable library configuration,因ؓ׃把需要的jar文g直接攑ֈWEB-INF下的lib目录中就可以了。所以不用配|。再下面的connectionq个是必要配置的要不我们怎么从数据库中生成啊。对不?br />
如果以前配置q连接直接选择可以了Q如果没有配|过点击 add connection.如下图:
选择要用的数据库类型,然后下一步,如下图。其实这个类型也没啥作用只是个生成连接字W串的模版而以?br />
选择已有的驱动,如果没有怎么办,废话Q当然是l箋新增了。这块不详述了,点击driver后面W一个按钮,Ҏ提示选择对应的jar文g卛_?br />
做完上述操作点击Finish.回到JPA FacetH口。选中Discover annotated classes automatically,把Create orm.xml钓掉。然后点Finish目徏完了?br />
然后在项目文件夹上右键选择JPA tools->Generate Entities from Tables.后如下图Q?br />
选择建好的connection如果没有connect connect一下。就会如上图所CZQ有时eclipse会有些小问题看不见表Q可以重启一下试试,实在不行q接徏个JPA project Q生成实体后再拷到自q目中就可以了。)选中要生成实体的表,Next如下图:
上面是表之间的关p,如果可以做相应的修改Q用的是ecipse 3.5貌似eclipse3.4q没q个功能Qeclipse来强了)Q再Next后如下图Q?br />
Q这个好像也是eclipse 3.5才加的)都能看明白吧。按照需要改改就可以了,q里不多啰嗦。再Next
后,如下图:
q是一些表的每个属性的调整Q一般也不用调了。Finish好了?br />
嘿嘿l于完成了。脓了这么多图,累死我了。不qؓ了大家能弄明白,q是图比文字更能说明情况Q我辛苦点就辛苦点吧。?br />
看看源码中生成的java文g是不是你惌的,具体q些cL么用。就不是q篇文章要说的问题了。如果大家有需要,我下回接着写?
]]>
Hibernate中Criteria的完整用?008q?7?9?星期?00:16最q在目中?Spring ?Hibernate q行开发,有感?Criteria 比较好用Q在查询Ҏ
设计上可以灵zȝҎ Criteria 的特Ҏ方便地进行查询条件的l装。现在对 Hibernate的Criteria 的用法进行ȝQ?br />
Hibernate 设计?CriteriaSpecification 作ؓ Criteria 的父接口Q下面提供了 Criteria和DetachedCriteria ?
Criteria ?DetachedCriteria 的主要区别在于创建的形式不一P Criteria 是在U的Q所
以它是由 Hibernate Session q行创徏的;?DetachedCriteria 是离U的Q创建时无需
SessionQDetachedCriteria 提供?2 个静态方?forClass(Class) ?forEntityName(Name)
q行DetachedCriteria 实例的创建?Spring 的框架提供了getHibernateTemplate
().findByCriteria(detachedCriteria) Ҏ可以很方便地ҎDetachedCriteria 来返回查询结
果?
Criteria ?DetachedCriteria 均可使用 Criterion ?Projection 讄查询条g。可以设
|?FetchMode( 联合查询抓取的模?) Q设|排序方式。对?Criteria q可以设|?FlushModel
Q冲?Session 的方式)?LockMode Q数据库锁模式)?
下面?Criterion ?Projection q行详细说明?br />
Criterion ?Criteria 的查询条件。Criteria 提供?add(Criterion criterion) Ҏ?br />
d查询条g?br />
Criterion 接口的主要实现包括: Example ?Junction ?SimpleExpression 。?
Junction 的实际用是它的两个子类 conjunction ?disjunction Q分别是使用 AND ?OR ?br />
作符q行来联l查询条仉合?br />
Criterion 的实例可以通过 Restrictions 工具cL创徏QRestrictions 提供了大量的静?br />
ҎQ如 eq Q等于)?ge Q大于等于)?between {来Ҏ的创?Criterion 查询条g
QSimpleExpression 实例Q。除此之外, Restrictions q提供了Ҏ来创?conjunction ?
disjunction 实例Q通过往该实例的 add(Criteria) Ҏ来增加查询条件Ş成一个查询条仉?br />
?br />
至于 Example 的创建有所不同Q?Example 本n提供了一个静态方?create(Object
entity) Q即Ҏ一个对象(实际使用中一般是映射到数据库的对象)来创建。然后可以设|一?br />
qo条gQ?
Example exampleUser =Example.create(u)
.ignoreCase() // 忽略大小?
.enableLike(MatchMode.ANYWHERE);
// ?String cd的属性,无论在那里值在那里都匹配。相当于 %value%
Project 主要是让 Criteria 能够q行报表查询Qƈ可以实现分组?Project 主要?
SimpleProjection ?ProjectionList ?Property 三个实现。其?SimpleProjection ?
ProjectionList 的实例化是由内徏?Projections 来完成,如提供的 avg ?count ?max ?
min ?sum 可以让开发者很ҎҎ个字D进行统计查询?
Property 是对某个字段q行查询条g的设|,如通过Porperty.forName(“color”).in
(new String[]{“black”,”red”,”write”}); 则可以创Z?Project 实例。通过
criteria ?add(Project) Ҏ加入到查询条件中厅R?
使用 Criteria q行查询Q主要要清晰的是 Hibernate 提供了那些类和方法来满开发中?br />
询条件的创徏和组装,下面介绍几种用法Q?br />
1. 创徏一个Criteria 实例
org.hibernate.Criteria接口表示特定持久cȝ一个查询。Session?Criteria实例的工厂?br />
Criteria crit = sess.createCriteria(Cat.class);
crit.setMaxResults(50);
List cats = crit.list();
2. 限制l果集内?br />
一个单独的查询条g是org.hibernate.criterion.Criterion 接口的一个实例?br />
org.hibernate.criterion.Restrictionsc?定义了获得某些内|Criterioncd的工厂方法?br />
List cats = sess.createCriteria(Cat.class)
.add( Restrictions.like("name", "Fritz%") )
.add( Restrictions.between("weight", minWeight, maxWeight) )
.list();
U束可以按逻辑分组?
List cats = sess.createCriteria(Cat.class)
.add( Restrictions.like("name", "Fritz%") )
.add( Restrictions.or(
Restrictions.eq( "age", new Integer(0) ),
Restrictions.isNull("age")
) )
.list();
List cats = sess.createCriteria(Cat.class)
.add( Restrictions.in( "name", new String[] { "Fritz", "Izi", "Pk" } ) )
.add( Restrictions.disjunction()
.add( Restrictions.isNull("age") )
.add( Restrictions.eq("age", new Integer(0) ) )
.add( Restrictions.eq("age", new Integer(1) ) )
.add( Restrictions.eq("age", new Integer(2) ) )
) )
.list();
Hibernate提供了相当多的内|criterioncd(Restrictions 子类), 但是其有用的是可以允许
你直接用SQL?br />
List cats = sess.createCriteria(Cat.class)
.add( Restrictions.sql("lower({alias}.name) like lower(?)", "Fritz%",
Hibernate.STRING) )
.list();
{alias}占位W应当被替换查询实体的列别名?
Property实例是获得一个条件的另外一U途径。你可以通过调用Property.forName() 创徏一?br />
Property?
Property age = Property.forName("age");
List cats = sess.createCriteria(Cat.class)
.add( Restrictions.disjunction()
.add( age.isNull() )
.add( age.eq( new Integer(0) ) )
.add( age.eq( new Integer(1) ) )
.add( age.eq( new Integer(2) ) )
) )
.add( Property.forName("name").in( new String[] { "Fritz", "Izi", "Pk" } ) )
.list();
3. l果集排?br />
你可以用org.hibernate.criterion.Order来ؓ查询l果排序?
List cats = sess.createCriteria(Cat.class)
.add( Restrictions.like("name", "F%")
.addOrder( Order.asc("name") )
.addOrder( Order.desc("age") )
.setMaxResults(50)
.list();
List cats = sess.createCriteria(Cat.class)
.add( Property.forName("name").like("F%") )
.addOrder( Property.forName("name").asc() )
.addOrder( Property.forName("age").desc() )
.setMaxResults(50)
.list();
4. 兌
你可以用createCriteria()非常Ҏ的在互相兌的实体间建立 U束?br />
List cats = sess.createCriteria(Cat.class)
.add( Restrictions.like("name", "F%")
.createCriteria("kittens")
.add( Restrictions.like("name", "F%")
.list();
注意W二?createCriteria()q回一个新?Criteria实例Q该实例引用kittens 集合中的元素?
接下来,替换形态在某些情况下也是很有用的?br />
List cats = sess.createCriteria(Cat.class)
.createAlias("kittens", "kt")
.createAlias("mate", "mt")
.add( Restrictions.eqProperty("kt.name", "mt.name") )
.list();
(createAlias()q不创徏一个新?Criteria实例?
Cat实例所保存的之前两ơ查询所q回的kittens集合?没有被条仉qo的。如果你希望只获?br />
W合条g的kittensQ?你必M用returnMaps()?
List cats = sess.createCriteria(Cat.class)
.createCriteria("kittens", "kt")
.add( Restrictions.eq("name", "F%") )
.returnMaps()
.list();
Iterator iter = cats.iterator();
while ( iter.hasNext() ) {
Map map = (Map) iter.next();
Cat cat = (Cat) map.get(Criteria.ROOT_ALIAS);
Cat kitten = (Cat) map.get("kt");
}
5. 动态关联抓?br />
你可以用setFetchMode()在运行时定义动态关联抓取的语义?
List cats = sess.createCriteria(Cat.class)
.add( Restrictions.like("name", "Fritz%") )
.setFetchMode("mate", FetchMode.EAGER)
.setFetchMode("kittens", FetchMode.EAGER)
.list();
q个查询可以通过外连接抓取mate和kittens?br />
6. 查询CZ
org.hibernate.criterion.Examplecd怽通过一个给定实?构徏一个条件查询?br />
Cat cat = new Cat();
cat.setSex('F');
cat.setColor(Color.BLACK);
List results = session.createCriteria(Cat.class)
.add( Example.create(cat) )
.list();
版本属性、标识符和关联被忽略。默认情况下gؓnull的属性将被排除?
可以自行调整Example使之更实用?
Example example = Example.create(cat)
.excludeZeroes() //exclude zero valued properties
.excludeProperty("color") //exclude the property named "color"
.ignoreCase() //perform case insensitive string comparisons
.enableLike(); //use like for string comparisons
List results = session.createCriteria(Cat.class)
.add(example)
.list();
甚至可以使用examples在关联对象上攄条g?br />
List results = session.createCriteria(Cat.class)
.add( Example.create(cat) )
.createCriteria("mate")
.add( Example.create( cat.getMate() ) )
.list();
7. 投媄(Projections)、聚合(aggregationQ和分组QgroupingQ?br />
org.hibernate.criterion.Projections?Projection 的实例工厂。我们通过调用
setProjection()应用投媄C个查询?
List results = session.createCriteria(Cat.class)
.setProjection( Projections.rowCount() )
.add( Restrictions.eq("color", Color.BLACK) )
.list();
List results = session.createCriteria(Cat.class)
.setProjection( Projections.projectionList()
.add( Projections.rowCount() )
.add( Projections.avg("weight") )
.add( Projections.max("weight") )
.add( Projections.groupProperty("color") )
)
.list();
在一个条件查询中没有必要昑ּ的?"group by" 。某些投q型就是被定义?分组投媄Q他
们也出现在SQL的group by子句中?
可以选择把一个别名指z一个投影,q样可以使投影DU束或排序所引用。下面是两种不同?br />
实现方式Q?br />
List results = session.createCriteria(Cat.class)
.setProjection( Projections.alias( Projections.groupProperty("color"), "colr" ) )
.addOrder( Order.asc("colr") )
.list();
List results = session.createCriteria(Cat.class)
.setProjection( Projections.groupProperty("color").as("colr") )
.addOrder( Order.asc("colr") )
.list();
alias()和as()Ҏ便的一个投影实例包装到另外一?别名的Projection实例中。简而言之,
当你d一个投影到一个投影列表中?你可以ؓ它指定一个别名:
List results = session.createCriteria(Cat.class)
.setProjection( Projections.projectionList()
.add( Projections.rowCount(), "catCountByColor" )
.add( Projections.avg("weight"), "avgWeight" )
.add( Projections.max("weight"), "maxWeight" )
.add( Projections.groupProperty("color"), "color" )
)
.addOrder( Order.desc("catCountByColor") )
.addOrder( Order.desc("avgWeight") )
.list();
List results = session.createCriteria(Domestic.class, "cat")
.createAlias("kittens", "kit")
.setProjection( Projections.projectionList()
.add( Projections.property("cat.name"), "catName" )
.add( Projections.property("kit.name"), "kitName" )
)
.addOrder( Order.asc("catName") )
.addOrder( Order.asc("kitName") )
.list();
也可以用Property.forName()来表C投影:
List results = session.createCriteria(Cat.class)
.setProjection( Property.forName("name") )
.add( Property.forName("color").eq(Color.BLACK) )
.list();
List results = session.createCriteria(Cat.class)
.setProjection( Projections.projectionList()
.add( Projections.rowCount().as("catCountByColor") )
.add( Property.forName("weight").avg().as("avgWeight") )
.add( Property.forName("weight").max().as("maxWeight") )
.add( Property.forName("color").group().as("color" )
)
.addOrder( Order.desc("catCountByColor") )
.addOrder( Order.desc("avgWeight") )
.list();
8. ȝ(detached)查询和子查询
DetachedCriteriacM你在一个session范围之外创徏一个查询,q且可以使用L?Session?br />
执行它?br />
DetachedCriteria query = DetachedCriteria.forClass(Cat.class)
.add( Property.forName("sex").eq('F') );
//创徏一个Session
Session session = .;
Transaction txn = session.beginTransaction();
List results = query.getExecutableCriteria(session).setMaxResults(100).list();
txn.commit();
session.close();
DetachedCriteria也可以用以表C子查询。条件实例包含子查询可以通过 Subqueries或?br />
Property获得?br />
DetachedCriteria avgWeight = DetachedCriteria.forClass(Cat.class)
.setProjection( Property.forName("weight").avg() );
session.createCriteria(Cat.class)
.add( Property.forName("weight).gt(avgWeight) )
.list();
DetachedCriteria weights = DetachedCriteria.forClass(Cat.class)
.setProjection( Property.forName("weight") );
session.createCriteria(Cat.class)
.add( Subqueries.geAll("weight", weights) )
.list();
怺兌的子查询也是有可能的Q?br />
DetachedCriteria avgWeightForSex = DetachedCriteria.forClass(Cat.class, "cat2")
.setProjection( Property.forName("weight").avg() )
.add( Property.forName("cat2.sex").eqProperty("cat.sex") );
session.createCriteria(Cat.class, "cat")
.add( Property.forName("weight).gt(avgWeightForSex) )
.list();
]]>
QBC查询Q?/span>
QBC查询是通过使用Hibernate提供?/span>Query By Criteria API来查询对象,q种API装?/span>SQL语句的动态拼装,Ҏ询提供了更加面向对象的功能接口。我们看下面的示例程序:
Criteria criteria=session.createCriteria(User.class);
criteria.add(Expression.eq(“name”,”zx”));
criteria.add(Expression.eq(“age”,new Integer(27));
List list=criteria.list();
当执?/span>criteria.list()时会生成cMq样?/span>SQL语句Q?/span>Select * from user where name=’zx’ and age=27;所以在q里我们可以看出Q?/span>Criteria实际上是一个查询容器,它对查询条g表达式的dq行了封装,具体的查询条件是通过add()Ҏd的,而且具体的查询条件的表达式运是通过Expression指定的?/span>Hibernate在运行期会根?/span>Criteria指定的表辑ּ条g来添加查询条Ӟq且生成查询语句。这U方式非常符?/span>Java以及所有面向对象编E语a的编E方式,所以大多数的持久层框架都提供了对这U方式查询的支持。下面我们讲解这U查询方式的各个技术细节?/span>
1?/span>Criteria查询表达式:
正如我们所见,ExpressionҎ询语句的表达式进行了装和限Ӟ下表列出?/span>Expression所有的ҎQ以及每个方法所对应的查询表辑ּ及其限制?/span>
注意Q?/span>Expression各方法中的属性参敎ͼ各方法中的第一个参敎ͼ所指定的属性名Uͼ如:name,sexQ,q不是数据库表中的实际字D名Uͼ而是实体对象中映实际数据表字段的类属性名U?/span>
2?/span>CZ查询Q?/span>
CZ查询是通过ExamplecL完成的,ExamplecdCCriterion接口Q可以用?/span>Criteria查询条gQ?/span>Examplecȝ作用是:Ҏ已有对象Q查询属性g之相同的其他对象。如下代码所C:
Criteria criteria=session.createCriteria(User.class);
User exampleuser=new User(“zx”);
criteria.add(Example.create(exampleuser));
List list=criteria.list();
for(int i=0;i
User user=(User)list.get(i);
System.out.println(user.getName()+”\n”);
}
上述代码?/span>User exampleuser=new User(“zx”);criteria.add(Example.create(exampleuser));两句相当?/span>
criteria.add(Expression.eq(“name”,”zx”));因此会生成类似如下的SQL语句Q?/span>
select * from user where name=’zx’;在上面的代码?/span>exampleuserUCؓCZ对象?/span>
?/span>Hibernate中队CZ查询Q默认情况下会排除掉CZ对象中属性gؓI的属性,q可以调?/span>Example.excludeNoneQ排除空串|/excludeZerosQ排除零|Q或者调?/span>Example.excludePropertyҎ来指定排除特定属性?/span>
CZ查询主要应用于组合查询中Q比如根据用戯入的查询条g动态生成最l的查询语句Q通过使用CZ查询Q可以避免由于查询条件过多而写的大?/span>if判断语句?/span>
3?/span>复合查询Q?/span>
复合查询主要是处理,h兌关系的两个实体怎样q行兌查询Q比?/span>User实体对象?/span>Addres实体对象h一对多的关联关p,我们可以如下构造符合查询:
Criteria criteria=session.createCriteria(User.class);
Criteria addcriteria=criteria.createCriteria(“addresses”);(1)
addcriteria.add(Express.like(“address”,”%tianjin%”));
List list=criteria.list();
for(int i=0;i
User user=(User)list.get(i);
System.out.println(user.getName()+”\n”);
Set addresses=user.getAddresses();
Iterator it=addresses.iterator();
while(it.hasNext(){
Address address=(Address)it.next();
System.out.println(address.getAddress()+”\n”);
}
}
当执行到了(1Q处Ӟ表明要针?/span>User对象?/span>addresses属性添加新的查询条Ӟ因此当执?/span>criteria.list()ӞHibernate会生成类似如下的SQL语句Q?/span>
Select * from user inner join address on user.id=address.id where address.address like ‘%shanghai%’;
正如我们所见,我们可以通过?/span>Criteria中添加保存关联对象的集合属性(addresses属性保存与User对象相关联的Address对象Q,来构造复合查询,在数据库一端是通过内连接查询来实现?/span>
4?/span>Criteria的高U特性:
A?/span>限定q回记录条数Q?/span>
我们可以通过利用Criteria.setFirstResult/setMaxResultҎ来限定返回某一ơ查询的记录敎ͼ如下代码Q?/span>
Criteria criteria=session.createCriteria(User.class);
criteria.setFirstResult(100);
criteria.setMaxResult(200);
通过以上代码可以讑֮该次查询q回user表中的从W?/span>100条记录开始直到第200条记录结束的100条记录?/span>
B?/span>Ҏ询结果进行排序:
可通过使用net.sf.hibernate.expression.Ordercd以对查询l果集进行排序,如下面代码:
Criteria criteria=session.createCriteria(User.class);
criteria.add(Expression.eq(“groupid”,”2”);
criteria.addOrder(Order.asc(“name”));
criteria.addOrder(Order.desc(“groupid”));
List list=criteria.list();
通过使用Ordercȝasc()/desc()ҎQ可以指定针Ҏ个字D늚排序逻辑Q如果执行上qC码,会生成类似如下的SQL语句Q?/span>
Select * from user where groupid=’2’ order by name asc,groupid desc
C?/span>分组与统计:
?/span>Hibernate3中,?/span>Criteria又增M新功能,可以支持分组与统计功能,?/span>Hibernate3中增加了Projections以及ProjectionListc,q两个类对分l与l计功能q行了封装,如下代码Q?/span>
Criteria criteria=session.createCriteria(User.class);
criteria.setProjection(Projections.groupProperty(“age”));(1)
List list=criteria.list();
Iterator it=list.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
通过Q?/span>1Q处的代码,我们通过ProjectionscL定了用于分组的目标属性,当进行检索时Hibernate会生成类似如下的SQL语句Q?/span>
Select age from user group by age;
q可以通过使用Projections?/span>avg()/rowCount()/count()/max()/min()/countDistinct(){方法来实现l计功能Q如下面的代码示例:
Criteria criteria=session.createCriteria(User.class);
criteria.setProjection(Projections.avg(“age”));(1)
List list=criteria.list();
Iterator it=list.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
通过Q?/span>1Q处的代码,我们实现了对用户q_q龄的统计,当进行检索时Q?/span>Hibernate会生成类似如下的SQL语句Q?/span>
Select avg(age) from user;
另外Q在SQL语句中的多条件分l与l计功能Q可以利?/span>ProjectionListcL实现Q如下面代码所C:
Criteria criteria=session.createCriteria(User.class);
ProjectionList prolist=Projections.projectionList();
prolist.add(Projections.groupProperty(“age”));
prolist.add(Projections.rowCount());
criteria.setProjection(prolist);
List list=criteria.list();
通过以上代码Q实C对不同年龄h员数量的分组l计Q当q行索时Q?/span>Hibernate会生成类似如下的SQL语句Q?/span>
Select age,count(*) from user group by age;
5?/span>DetachedCriteria:
?/span>Hibernate2中,Criteria实例是与创徏它的Session实例h相同的生命周期的Q也是_Session实例是它所创徏?/span>Criteria实例的宿主,?/span>Session关闭Ӟ寄生?/span>Session实例?/span>Criteria都将失效。这对Criteria的重用造成了困难,Z实现Criteria实例的重用,?/span>Hibernate3中提供了一?/span>DetachedCriteriac,DetachedCriteria实例的生命周期与Session实例的生命周期无养I我们可以利用DetachedCriteria对一些常用的Criteria查询条gq行抽离Q当需要进行检索时再与Session实例兌Q从而获得运行期?/span>Criteria实例。如下面的代码所C:
DetachedCriteria dc= DetachedCriteria.forClass(User.class);
dc.add(Expression.eq(“name”,”zhaoxin”));
dc.add(Expression.eq(“sex”,”1”));
Criteria criteria=dc.getExecutableCriteria(session);
Iterator it=criteria.list().iterator();
while(it.hasNext()){
User user=(User)it.next();
System.out.println(user.getName());
}
正如我们所见,DetachedCriteria的生存周期与session实例无关Q当需要进行检索时Q通过getExecutableCriteria(session)ҎQ与当前?/span>Session实例兌q获得运行期?/span>Criteria实例Q完成检索?/span>
DetachedCriteria也可以用于完成子查询功能Q如下代码所C:
DetachedCriteria dc= DetachedCriteria.forClass(User.class);
dc.setProjection(Projections.avg(“age”));
Criteria criteria=session.createCriteria(User.class);
criteria.add(Subqueries.propertyGt(“age”,dc));
List list=criteria.list();
通过Subqueriesc,实现了添加子查询的功能,我们?/span>DetachedCriteria所讑֮的查询条Ӟ当作子查询添加到了运行时Criteria实例的查询条件中Q当执行索时Hibernate会生成类似如下的SQL语句Q?/span>
Select * from user where age>(select avg(age) from user group by age);
|