??xml version="1.0" encoding="utf-8" standalone="yes"?> HQLq算W?/span> QBCq算W?/span> 含义 = Restrictions.eq() {于equal <> Restrictions.ne() 不等于not equal > Restrictions.gt() 大于greater than >= Restrictions.ge() 大于{于greater than or equal < Restrictions.lt() 于less than <= Restrictions.le() 于{于less than or equal is null Restrictions.isnull() {于I?/span> is not null Restrictions.isNotNull() 非空?/span> like Restrictions.like() 字符串模式匹?/span> and Restrictions.and() 逻辑?/span> and Restrictions.conjunction() 逻辑?/span> or Restrictions.or() 逻辑?/span> or Restrictions.disjunction() 逻辑?/span> not Restrictions.not() 逻辑?/span> in(列表) Restrictions.in() {于列表中的某一个?/span> not in(列表) Restrictions.not(Restrictions.in()) 不等于列表中L一个?/span> between x and y Restrictions.between() 闭区间xy中的L?/span> not between x and y Restrictions.not(Restrictions..between()) 于值X或者大于值y 一 Hibernate 设计?CriteriaSpecification 作ؓ Criteria 的父接口Q下面提供了 Criteria和DetachedCriteria ? List cats = sess.createCriteria(Cat.class) 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? List cats = sess.createCriteria(Cat.class) .add( Restrictions.sql("lower({alias}.name) like lower(?)", "Fritz%", Hibernate.STRING) ) .list(); {alias}占位W应当被替换查询实体的列别名? Property实例是获得一个条件的另外一U途径。你可以通过调用Property.forName() 创徏一?/p>
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果集排?/p>
你可以用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()非常Ҏ(gu)的在互相兌的实体间建立 U束?/p>
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 集合中的元素? 接下来,替换形态在某些情况下也是很有用的?/p>
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的。如果你希望只获?/p>
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. 动态关联抓? 你可以用setFetchMode()在运行时定义动态关联抓取的语义? List cats = sess.createCriteria(Cat.class) .add( Restrictions.like("name", "Fritz%") ) .setFetchMode("mate", FetchMode.EAGER) .setFetchMode("kittens", FetchMode.EAGER) .list(); q个查询可以通过外连接抓取mate和kittens?/p>
6. 查询CZ org.hibernate.criterion.Examplecd怽通过一个给定实?构徏一个条件查询?/p>
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?/p>
List results = session.createCriteria(Cat.class) .add( Example.create(cat) ) .createCriteria("mate") .add( Example.create( cat.getMate() ) ) .list(); 7. 投媄(Projections)、聚合(aggregationQ和分组QgroupingQ?/p>
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束或排序所引用。下面是两种不同?/p>
实现方式Q? 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()Ҏ(gu)便的一个投影实例包装到另外一?别名的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)查询和子查询 在web层,E序员用DetachedCriteria来构造查询条Ӟ然后这个DetachedCriteria作ؓҎ(gu)调用参数传递给业务层对象。而业务层对象获得DetachedCriteria之后Q可以在session范围内直接构造CriteriaQ进行查询。就此,查询语句的构造完全被搬离到web层实玎ͼ而业务层则只负责完成持久化和查询的封装即可,与查询条件构造完全解耦,非常完美Q这恐怕也是以前很多企囑֜web层代码中构造HQL语句的h惛_现的梦想吧! DetachedCriteriacM你在一个session范围之外创徏一个查询,q且可以使用L?Session?/p>
执行它? 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或?/p>
Property获得?/p>
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? 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(); 本文来自CSDN博客Q{载请标明出处Qhttp://blog.csdn.net/kjfcpua/archive/2009/06/21/4287248.aspx DetachedCriteria可以解决q个问题Q即在web层,E序员用DetachedCriteria来构造查询条Ӟ然后这?DetachedCriteria作ؓҎ(gu)调用参数传递给业务层对象。而业务层对象获得DetachedCriteria之后Q可以在session范围内直接构造CriteriaQ进行查询。就此,查询语句的构造完全被搬离到web层实玎ͼ而业务层则只负责完成持久化和查询的封装即可,与查询条件构造完全解耦,非常完美Q这恐怕也是以前很多企囑֜web层代码中构造HQL语句的h惛_现的梦想吧! CZ代码片段如下Q?/p>
web层程序构造查询条Ӟ Java代码: Department和Employee是一对多兌Q查询条件ؓQ?/p>
名称?#8220;department”开发部门; 业务层对象用该条g执行查询Q?/p>
java代码: detachedCriteria.getExecutableCriteria(session).list(); 然而Spring和Hibernate3的DetachedCriteria有不兼容的问题,因此在Spring环境下面使用Hibernate3需要注意: Spring的HibernateTemplate提供了Hibernate的完封装,即通过匿名cd现回调,来保证Session的自动资源管理和事务的管理。其中核心方法是Q?/p>
java代码: web层代码: java代码: 业务层代码用springQDepartmentManager的findByCriteria如下Q?/p>
java代码: public List findByCriteria(final DetachedCriteria detachedCriteria) { java代码: 但是该程序代码执行,会抛出强制类型{换异常! 我跟t了一下spring和Hibernate源代码,原因如下Q?/p>
spring的HibernateTemplate的executeҎ(gu)提供的回调接口具有Session作ؓ参数Q但是实际上Q默认情况下Q?HibernateTemplate传递给回调接口的sessionq不是org.hibernate.impl.SessionImplc,而是 SessionImplcȝ一个ProxycR之所以替换成Z个Proxyc,HibernateTemplate的注释说明,Proxy提供了一些额外的功能Q包括自动设|CachableQTransaction的超时时_Session资源的更U极的关闭等{?/p>
java代码: 但是遗憾的是QHibernate的DetachedCriteria的setExecutableCriteriaҎ(gu)却要求将session参数强制转ؓSessionImplQ但是spring传过来的却是一个Proxyc,因此报错了?/p>
java代码: 解决Ҏ(gu)Q禁止Spring的HibernateTemplate传递Proxyc,强制要求它传递真实的SessionImplc,即给exexuteҎ(gu)增加一个参敎ͼ提供参数为trueQ如下: java代码: 3 Qfind ( String queryString ) : Ҏ(gu)HQL查询字符串来q回实例集合 4 QfindByNamedQuery ( String queryName) : Ҏ(gu)命名查询q回实例集合 5 Qget ( Class entityClass , Serializable id ) : Ҏ(gu)主键加蝲特定持久化类的实?br />
public Person getPerson() 7 QsaveOrUpdate ( Object entity ): Ҏ(gu)实例状态,选择保存或者更?/p>
8 Qupdate ( Object entity ) : 更新实例的状态,要求entity是持久状?/p>
9 QsetMaxResults ( int maxResults ) : 讄分页的大?/p>
理二~存 一U缓存和二~存的交互问?br />
1 不设|?默认)会写入二U缓存,也会d 3 PUT只写入二U缓存页不读?/p>
查询~存是针Ҏ(gu)通属性结果集的缓?br />
对实体对象的l果只缓存id 查询~存的生命周期,当前兌的表发生修改Q那么查询缓存生命周期结?/p>
查询~存的配|和使用 * 在程序中昑ּL 2 Session和查询缓存生命周期没有关p?br />
3 查询~存对query.iterate()不v作用Q只用对query.list()起作?br />
(zhn)观锁的实现Q通常依赖于数据库机制Q在整个q程中将数据锁定Q其它Q何用户都不能d或修?br />
session.load(Inventory.class, 1, LockMode.UPGRADE); 乐观?/p>
大多数基于数据版本记录机?version)实现Q一般是在数据库表中加入一个version字段 session flushҎ(gu)主要做了两g事: session在什么情况下执行flush hibernate按照save(insert),update,delete序提交相关的操?br />
------------------------------------------------------------------------ <id name="id">
13:35:42,254 INFO Configuration:332 - Reading mappings from file: D:\opt\ASF\Tomcat6.0\webapps\cityunion\WEB-INF\classes\com\c6\orm\model\bull\BullInfo.hbm.xml
13:35:42,442 INFO HbmBinder:322 - Mapping class: com.c6.orm.model.bull.BullInfo -> TB_BULL_INFO
13:35:42,442 INFO Configuration:332 - Reading mappings from file: D:\opt\ASF\Tomcat6.0\webapps\cityunion\WEB-INF\classes\com\c6\orm\model\coin\CardInfo.hbm.xml
13:35:42,457 INFO HbmBinder:322 - Mapping class: com.c6.orm.model.coin.CardInfo -> TB_CARD_INFO
13:35:42,473 INFO Configuration:332 - Reading mappings from file: D:\opt\ASF\Tomcat6.0\webapps\cityunion\WEB-INF\classes\com\c6\orm\model\coin\Payment.hbm.xml
13:35:42,489 INFO HbmBinder:322 - Mapping class: com.c6.orm.model.coin.Payment -> TB_PAYMENT
13:35:42,489 INFO Configuration:332 - Reading mappings from file: D:\opt\ASF\Tomcat6.0\webapps\cityunion\WEB-INF\classes\com\c6\orm\model\coin\TbBankExchangeLog.hbm.xml
。。。。。。。。。。。?br />
描述Q提CZ息Unable to verify action class exists at initialization
不停的加?hbm.xml文gQ导致tomcat无法启动?br />
被提CZ息误|在网上找了大量资料,都没有解冟뀂原来由于自已不心写错了配|文?br />
<property name="slaveSelfTotal" type="int" column="SLAVE_SELF_TOTAL"/>
<property name="slaveSelfTotal" type="int" column="SLAVE_SELF_TOTAL"/>
写了两次?br />
出现些问题大多是因ؓ配置文g出错而引LQ仔l查看最q修改的|配文g找到问题了
]]>import org.hibernate.cfg.Configuration;
import org.hibernate.tool.hbm2ddl.SchemaExport;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
Configuration cfg=new Configuration().configure();
SchemaExport export=new SchemaExport(cfg);
export.create(true, true);
}
}
]]><?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd" >
<hibernate-configuration>
<session-factory>
<property name="connection.driver_class">com.microsoft.sqlserver.jdbc.SQLServerDriver</property>
<property name="connection.url">jdbc:sqlserver://localhost:1433;DatabaseName=epai</property>
<property name="connection.username">sa</property>
<property name="connection.password">accp</property>
<property name="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<property name="hibernate.current_session_context_class">thread</property>
<!--
<property name="hibernate.current_session_context_class">jta</property>
-->
<mapping resource="org/epai/entity/Users.hbm.xml"/>
<mapping resource="org/epai/entity/Goods.hbm.xml"/>
<mapping resource="org/epai/entity/Bid.hbm.xml"/>
</session-factory>
</hibernate-configuration>
]]>
//获取记录L
recordCount=Convert.ToInt32(criteria.SetProjection( Projections.Count(MovieUrl.__ID )) .UniqueResult( ));
criteria.SetProjection( null );
Criteria c=session.createCriteria(Book.class);
c.add(Restrictions.like("bookname", "a",MatchMode.ANYWHERE));
c.add(Restrictions.between("bid", 1, 3));
c.add(Restrictions.not(Restrictions.in("bid", new Integer[]{1,2,4})));
c.setFirstResult(0);
c.setMaxResults(2);
List list=c.list();
Restrictions.like(“”,…,MatchMode.ANYWHERE)
AddOrder(Order.asc(“fwid”))
在oracle数据库中Q如果?span style="font-size: 12pt; font-family: 宋体">Restrictions.ne("name","张三")Q不会包括该字段gؓI的记录
]]>
1 Criteria ?DetachedCriteria 的主要区别在于创建的形式不一P Criteria 是在U的Q所
以它是由 Hibernate Session q行创徏的;?DetachedCriteria 是离U的Q创建时无需SessionQDetachedCriteria 提供?2 个静态方?forClass(Class) ?forEntityName(Name)
q行DetachedCriteria 实例的创建?Spring 的框架提供了getHibernateTemplate().findByCriteria(detachedCriteria) Ҏ(gu)可以很方便地Ҏ(gu)DetachedCriteria 来返回查询结果?
2 Criteria ?DetachedCriteria 均可使用 Criterion ?Projection 讄查询条g。可以设
|?FetchMode( 联合查询抓取的模?) Q设|排序方式。对?Criteria q可以设|?FlushModel
Q冲?Session 的方式)?LockMode Q数据库锁模式)?
?下面?Criterion ?Projection q行详细说明Q?br />
1 Criterion ?Criteria 的查询条件。Criteria 提供?add(Criterion criterion) Ҏ(gu)?br />
d查询条g?br />
2 Criterion 接口的主要实现包括: Example ?Junction ?SimpleExpression 。?
Junction 的实际用是它的两个子类 conjunction ?disjunction Q分别是使用 AND ?OR ?br />
作符q行来联l查询条仉合?br />
3 Criterion 的实例可以通过 Restrictions 工具cL创徏QRestrictions 提供了大量的静?br />
Ҏ(gu)Q如 eq Q等于)?ge Q大于等于)?between {来Ҏ(gu)的创?Criterion 查询条g
QSimpleExpression 实例Q。除此之外, Restrictions q提供了Ҏ(gu)来创?conjunction ?
disjunction 实例Q通过往该实例的 add(Criteria) Ҏ(gu)来增加查询条件Ş成一个查询条仉合?br />
4 至于 Example 的创建有所不同Q?Example 本n提供了一个静态方?create(Object entity)Q?br />
x据一个对象(实际使用中一般是映射到数据库的对象)来创建。然后可以设|一些过滤条Ӟ
Example exampleUser =Example.create(u).ignoreCase() // 忽略大小?
.enableLike(MatchMode.ANYWHERE);
// ?String cd的属性,无论在那里值在那里都匹配。相当于 %value%
5 Project 主要是让 Criteria 能够q行报表查询Qƈ可以实现分组?Project 主要?
SimpleProjection ?ProjectionList ?Property 三个实现。其?SimpleProjection ?
ProjectionList 的实例化是由内徏?Projections 来完成,如提供的 avg ?count ?max ?
min ?sum 可以让开发者很Ҏ(gu)Ҏ(gu)个字D进行统计查询?
6 Property 是对某个字段q行查询条g的设|,如通过Porperty.forName(“color”).in
(new String[]{“black”,”red”,”write”}); 则可以创Z?Project 实例。通过
criteria ?add(Project) Ҏ(gu)加入到查询条件中厅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的工厂方法?
.add( Restrictions.like("name", "Fritz%") )
.add( Restrictions.between("weight", minWeight, maxWeight) )
.list();
例子
public List findAllByCriter(final DetachedCriteria detachedCriteria){
return (List)getHibernateTemplate().execute(new HibernateCallback(){
public Object doInHibernate(Session session)
throws HibernateException{
Criteria criteria=detachedCriteria.getExecutableCriteria(session);
return criteria.list();
}
});
}
-----------------------------------------------------------------------------------------
Hibernate一直都认ؓ比较?那么媄一下:Q但最q项目当中遇见很多问题,今天看见别h在项目当中用了 Hibernate3的DetachedCriteriaQ感觉真的是太好了,于是p了点旉研究了一下,希望和大家分享一下吧
针对q种需求,对于分层应用E序来说QWeb层需要传递一个查询的条g列表l业务层对象Q业务层对象获得q个条g列表之后Q然后依ơ取出条Ӟ构造查询语句。这里的一个难Ҏ(gu)条g列表用什么来构造?传统上用MapQ但是这U方式缺陷很大,Map可以传递的信息非常有限Q只能传递name?valueQ无法传递究竟要做怎样的条件运,I竟是大于,于QlikeQ还是其它的什么,业务层对象必ȝ切掌握每条entry的隐含条件。因此一旦隐含条件改变,业务层对象的查询构造算法必ȝ应修改,但是q种查询条g的改变是隐式U定的,而不是程序代码约束的Q因此非常容易出错?/p>
DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Department.class);
detachedCriteria.add(Restrictions.eq("name", "department")).createAlias("employees", "e").add(Restrictions.gt(("e.age"), new Integer(20)));
部门里面的雇员年龄大?0岁;
最大的意义在于Q业务层代码是固定不变的Q所有查询条件的构造都在web层完成,业务层只负责在session内执行之。这样代码就可放之四皆准,都无M改了?/p>
HibernateTemplate.execute(new HibernateCallback() {
public Object doInHibernate(Session session) throws HibernateException {
....
}
}
回调Ҏ(gu)提供了session作ؓ参数Q有了sessionQ就可以自由的用Hibernate API~程了。用了spring的之后,代码修改如下Q?/p>
DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Department.class);
detachedCriteria.createAlias("employees", "e").add(Restrictions.eq("name", "department")).add(Restrictions.gt(("e.age"), new Integer(20)));
departmentManager.findByCriteria(detachedCriteria);
构造detachedCriteriaQ作为参C递给departmentManager
return (List) getHibernateTemplate().execute(new HibernateCallback() {
public Object doInHibernate(Session session) throws HibernateException {
Criteria criteria = detachedCriteria.getExecutableCriteria(session);
return criteria.list();
}
});
}
实际上也是Q?/p>
Criteria criteria = detachedCriteria.getExecutableCriteria(session);
return criteria.list();
而已
private boolean exposeNativeSession = false;
...
executeҎ(gu)内部Q?br />
Session sessionToExpose = (exposeNativeSession ? session : createSessionProxy(session));
public Criteria getExecutableCriteria(Session session) {
impl.setSession( (SessionImpl) session ); // 要求SessionImplQSpring传递的是Proxy
return impl;
}
public List findByCriteria(final DetachedCriteria detachedCriteria) {
return (List) getHibernateTemplate().execute(new HibernateCallback() {
public Object doInHibernate(Session session) throws HibernateException {
Criteria criteria = detachedCriteria.getExecutableCriteria(session);
return criteria.list();
}
}, true);
}
]]>
{
//先加载特定的实例
Object p = getHibernateTemplate().load( Person.class , new Integer( personid));
//删除特定实例
getHibernateTemplate().delete (p);
}
2 QdeleteAll ( Collection entities ) : 删除集合内全部持久化cd?/p>
Public List getPersons()
{
//q回Person的全部实?br />
return getHibernateTemplate().find ( " from Person " );
}
{
//q回特定主键对应的Person实例
return (Person)getHibernateTemplate().get (Person.class , new Integer(person id));
}
6 Qsave ( Object entity ) : 保存新的实例
HibernateTemplate?更灵z?的用?Q?br />
更灵zȝ讉K是通过以下两个Ҏ(gu)完成?
Object execute ( HibernateCallback action ) ;
List execute ( HibernateCallback action );
q两个方法都需要一个HibernateCallback的实例,可以在Q何有效的hibernate数据讉K中用。用法灵z,解决了Spring装Hibernate后灵zL不的~陷?HibernateCallback 是一个接Q该接口只有一个方doInHibernate ( org.hibernate.Session session ), 该方法只有一个参数Session.
public class PersonDaolmpl implements PersonDao
{
// U有实例变量保存SessionFactory
private SessionFactory sessionFactory;
// 依赖注入必需的setter Ҏ(gu)
public void setSessionFactory(SessionFactory sessionFactory)
{
this.sessionFactory = sessionFactory;
}
/**
*通过人名查找所有匹配该名的Person 实例
* @param name 匚w的h?br />
* @return 匚w该Q命的全部Person 集合
*/
public List findPersonsByName(final String name)
//创徏HibernateTemplate实例
HibernateTemplate hibernateTemplate = new HibernateTemplate(this.sessionFactory);
//q回HibernateTemplate的execute 的结?/span>
return (List) hibernateTemplate.execute (
//创徏匿名内部c?/span>
new HibernateCallback ()
public Object doInHibernate (Session session)
throws Hibernate Exception
{
//使用条g查询的方法返?/span>
List result = session.createCriteria(Person.class)
.add(Restrictions.like("name", name+ " %") .list ( ) ;
return result;
} ) :
}
}
注意Q?/span>在方法doInHibernate内可以访问到SessionQ该session是完全绑定到当前U程的Session实例Q保证在对于复杂的持久层讉KӞ依然可以使用Hibernate的访问方式?
]]>
]]>
* 一U缓存是~存实体对象?br />
* 如果理一U缓?br />
一U缓存无法取消,但可以管理clear(),evict()
* 一U缓存和session的生命周期一_一U缓存也叫sessionU的~存或事务~存
* 如何避免一ơ性大量的实体数据入库D内存溢出
先flush,再clear
* 如何理一U缓?br />
load,get,iterate,save都支持一U缓?br />
如果数据量特别大Q考虑采用jdbc实现Q如查jdbc也不能满求可以考虑采用数据本n的特定导入工?
Student student=(Student)session.load(Student.class,1);
System.out.println("studnet.name="+student.getName());
//不会发出sqlQ因为load使用~存
Student student=(Student)session.load(Student.class,1);
System.out.println("studnet.name="+student.getName());
二~存
* 二~存是缓存实体对象的Q普通属性不会缓?br />
* 二~存是进E的缓?也称为SessionFactoryU的~存,可以被所有的session׃n
二~存的生命周期和SessionFactory是一致的Q可以用SessionFactory理二~存
* 二~存的配|和使用
1 加入ehcache的jar?
2 拯ehcache.xml文g到src目录?
3 开启二U缓存,默认是打开的。配|hibernate.cfg.xml
hibernate.cfg.xml文g
开启二U缓?
<property name="hibernate.cache.use_second_level_cache">true</property>
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
* 在映文件中采用<cache>标签
<class name="com.my.hibernate.User" table="t_user">
<cache usage="read-only"/>
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<many-to-one name="group" column="groupid" cascade="save-update"/>
</class>
<class-cache class="com.bjsxt.hibernate.Studnet" usage="read-only"/>
factory.evict(Student.class);
factory.evict(Student.class,1);
2 GET只读而不写入二~存 session.setCacheMode(CacheMode.GET);
Student student=(Student)session.load(Student.class,1);
session.setCacheMode(CacheMode.PUT);
Student student=(Student)session.load(Student.class,1);
查询~存
1 L查询~存
* 配置hibernate.cfg.xml文g<property name="hibernate.cache.use_second_level_cache">true</property>
query.setCacheable(true);
]]>
d数据时将版本号一同读出,之后更新数据时版本号加一Q如果提交数据时片本号小?br />
或等于数据库表中的版本号Q则认ؓ数据是过期的Q否则给予更新?br />
private int id;
private String name;
private int count;
private int version;
//version版本L数据库维护,我们不用?/span>
<class name="Inventory" table="t_inventory2" optimistic-lock="version">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<property name="count"/>
<property name="version"/>
</class>
]]>
1 清理~存
2 执行sql(不是提交事务)
1 默认在事务提交时
2 昑ּ的调用flush
3 在执行查询前Q如Qiterate
<generator class="uuid"/>
</id>
因ؓid的主键生成策略采用的是uuid,所以调用完save后,只是user对象U_到session的管?br />
不会发出insert语句Q但是id已经生成Qsession中existsInDatebase状态ؓfalse
session.save(user);
调用flush,hibernate会清理缓存,执行sql
如果数据库的隔离U别为提交读Q那么我们可以看到flushq的数据
q且session中existsInDatebase状态变为true
session.flush();
默认情况下commit操作会先执行者f(xi)lush清理~存Q所以不用显式的调用flush
commit后数据无法回?br />
session.getTransaction().commit();
<id name="id">
<generator class="native"/>
</id>
如果id的主键生成策略采用的是native,调用save(user)时会发出insert语句Q返回由数据库生成的id,
user对象U_到session的管?session中existsInDatebase状态ؓtrue
-----------------------------------------------------------------
<id name="id">
<generator class="uuid"/>
</id>
session.save(user);
user对象从session中逐出,即session的EntiryEntries属性中逐出
session.evict(user);//清理~存
无法成功提交Q因为hibernate在清理缓存时Q在session的insertions集合中取出user对象q行insert操作?br />
需要更新entityEntries属性中的existsnDatabase为true,而我们采用evict已经user从session?br />
逐出?所以找不到相关数据,无法更新,抛出异常
session.getTransaction().commit();
----------------------------------------------------------------
<id name="id">
<generator class="uuid"/>
</id>
session.save(user);
flush后hibernate会清理缓?会将user对象保存到数据库?session中的insertions中的user
清除,q且讄session中existsInDatabase的状态ؓtrue
session.flush(user);
user对象从session中逐出,即session的EntityEntries属性中逐出
session.evict(user);//清理~存
可以成功提交Q因为hibernate在清理缓存时Q在session的insertions集合中无法找到user对象
所以就不会发出insert语句,也不会更新session中的existsInDatabase的状?br />
session.getTransaction().commit();
-----------------------------------------------------------------
<id name="id">
<generator class="native"/>
</id>
session.save(user);
user对象从session中逐出,即session的EntityEntries属性中逐出
session.evict(user);//清理~存
可以成功提交Q因为hibernate在清理缓存时Q在session的insertions集合中无法找到user对象
所以就不会发出insert语句,也不会更新session中的existsInDatabase的状?br />
session.getTransaction().commit();
-----------------------------------------------------------------
<id name="id">
<generator class="assigned"/>
</id>
session.save(user);
user.setName("张三");
session.update(user);
User user2=new User();
user2.setId("003");
user2.setName("李四");
session.getTransaction().commit();
l果:
insert into ...
insert into ...
update t_user ...
hibernate按照save(insert),update,delete序提交相关的操?br />
-----------------------------------------------------------------
<id name="id">
<generator class="assigned"/>
</id>
session.save(user);
user.setName("张三");
session.update(user);
因ؓ我们在session.update(user)后执行了flush,所以在以commit清理~存时执行flush前的sql׃会发?
session.flush();//在这里flush操作可以了
User user2=new User();
user2.setId("003");
user2.setName("李四");
session.getTransaction().commit();
l果:
insert into ...
update t_user ...
insert into ...
按照我们惌序save(insert),update,save(insert)的顺序提交操?br />
-----------------------------------------------------------------
]]>
1 保持默认,也就是fetch="select"
<many-to-one name="classes" column="classesid" cascade="save-update"/>
fetch="select",另外发送一条select语句抓取当前对象兌实体或集?br />
2 讄fetch="jion"
<many-to-one name="classes" column="classesid" cascade="save-update" fetch="join"/>
fetch="jion",hibernate会通过select语句会用外联接来加载其兌实体或集?此时lazy会失?br />
------------------------------------------------------------
抓取{略(集合代理的批量抓?
1 保持默认,也就是fetch="select"
<set name="students" fetch="select">
fetch="select",另外发送一条select语句抓取当前对象兌实体或集?br />
2 讄fetch="jion"
<set name="students" fetch="jion">
fetch="jion",hibernate会通过select语句会用外联接来加载其兌实体或集?此时lazy会失?br />
3 讄fetch="subselect"
<set name="students" fetch="subselect">
fetch="subselect",用于createQuery()查询,另外发送一条select语句抓取在前面查询到的所有实体对象的兌集合
----------------------------------------------------------------
抓取{略,batch-size?lt;class>上的应用
batch-size属?可能扚w加蝲体类,参见:Classes.hbm.xml
<class name="Classes" table="t_classes" batch-size="3">
在hibernate.cfg.xml中设|?br /> <property name="hibernate.jdbc.fetch_size">50</property>
在hibernate?component是某个实体的逻辑l成部分Q它与实体的Ҏ(gu)区别是没有oidQ?br /> component可以UCؓ是值对象(DDDQ?/p>
采用component映射的好处:它实C对象模型的细_度划分Q层ơ会更分明,复用率会更高
复合Q联合)主键映射
通常复合主键相关的属性,单独攑ֈ一个类?br /> * 此类必须实现序列化接?br /> * 覆写hashcode和equalsҎ(gu)
<id/>标签 -主键
主键生成{略Q?br />
uuid native 和assigned
<id
*name="propertyName" (1)
type="typename" (2)
*column="column_name" (3)
unsaved-value="null|any|none|undefined|id_value" (4)
access="field|property|ClassName" (5)
node="element-name|@attribute-name|element/@attribute|.">
*length (6)
<generator class="generatorClass"/>
</id>
(1) name (可?: 标识属性的名字?
(2) type (可?: 标识Hibernatecd的名字?
(3) column (可?- 默认为属性名): 主键字段的名字?
(4) unsaved-value (可?- 默认Z个切合实际(sensibleQ的?: 一个特定的标识属性|用来标志该实例是刚刚创徏的,未保存?q可以把q种实例和从以前的session中装载过Q可能又做过修改--译者注Q?但未再次持久化的实例区分开来?
(5) access (可?- 默认为property): Hibernate用来讉K属性值的{略?
(6) 长度.