http://www.cnblogs.com/helong/articles/2096216.html
Example.excludeProperty
Example作用是:根据以后的对象,查找属性之间的相符的其它对象 用法:
Criteria criteria = session.createCriteria(TUser. class );TUser exUser = new TUser();exUser.setName( " Erica " );criteria.add(Example.create(exUser));
这里我们新建一个TUser对象exUser,并作为范本,查询所有的name属性与之相同的用户记录 上列语句等同于: Criteria criteria = session.createCriteria(TUser.class);criteria.add(Expression.eq("name","Erica")); 默认情况下,Hibernate会过滤掉是列对象的NUll值属性,我们也可以通过调用Example.excludeNone/excludeZeroes 方法来对这个特性进行调整,或者通过Example.excludeProperty方法将某个属性排除在外 举例描述Example类的用途 大部分我们会在代码中进行判断,根据用户输入的查询生成最终的查询条件,由于组合条件不确定,往往导致逻辑判断语句拖沓起伏,如下:
public List querUsers(String name,Integer age) throws HibernateException{Criteria criteria = session.craeteCriteria(TUser. class );if ( null != name){criteria.add(Expression.like( " name " ,name))}if ( null != age){criteria.add(Expression.eq( " age " ,age));}return criteria.list();}
对于上面的例子,如果出现了十个,那么情况相当复杂,示例查询在这里,就可以起到相当大的作用,我们可以修改如下:
public List querUsers(TUser user){Criteria criteria = session.createCriteria(TUser. class );criteria.add(Example.create(user));return criteria.list();}
Hibernate复合查询
Criteria criteria = session.createCriteria(TUser. class ); Criteria addrCriteria = criteria.createCriteria( " addresses " ); addrCriteria.add(Expression.like( " address " , " %Shanghai " ));
运行后Hibernate显示的SQL语句如下:
select ... fromT_USER user inner join T_Address address on user .id = address. user_id where address.address like ?
Hibernate DetachedCriteria
由某个Session创建的Criteria实例,一旦Session销毁,那么此Criteria实例也随之实效,这很大的程度上限制了Criteria的重用,对于相同的Criteria查询条件,每次我们都必须由当前Session构造其查询实例,未免失之繁琐。
DetachedCriteria 可以脱离Session实例独立存在,这样,我们就可以将某些通用的Criteria查询条件进行抽离,每次使用时在与当前Session实例绑定以获得更好的代码重用效果,用法如下:
DetachedCriteria deCriteria = DetachedCriteria.forClass(TUser. class ); deCriteria.add(Expression.eq( " name " , " Erica " )); deCriteria.add(Expression.eq( " sex " , new Integer( 1 ))); Criteria criteria = deCriteria.getExecutableCriteria(session); List list = criteria.list();
我们可以采用DetachedCriteria实现子查询,例子如下:
DetachedCriteria avgAge = DetachedCriteria.forClass(TUser. class ); avgAge.setProjection(Projections.avg( " avg " )); Criteria criteria = session.createCriteria(TUser. class ); criteria.add(Subqueries.propertyGt( "age" ,avgAge)); List list = criteria.list();
通过Subqueries我们可以将DetachedCriteria纳入查询表达式,反映SQL上则是一个典型的子查询语句,上例运行期生成的SQL语句大致如下:
select ... from T_USER user where age > ( select avg (age) from T_USER)
Hibernate Criteria 分组于统计
下列我们采用TUser对象中的age分组
Criteria criteria = session.createCriteria(TUser. class ); criteria.setProjection(Projections.groupProptery( " age " )); List list criteria.list();
通过上例运行期大概生成的SQL语句如下:
select this.age as y0_ from T_USER this_ group by this_.age
可以看到Projections.groupProperty()方法实际上是对SQL group by 子句的封装,同样,我们可以通过Projections.avg()、rowCount()、count()、max()、min()、countDistinct()等方法实现查询统计功能。
另外,对于多条件组合的统计、分组功能,我们可以借助ProjectionList完成,下面例子中,我们统计了各个年龄层次中的用户数量:
ProjectionList projectionList = Projections.projectionList(); projectionList.add(Projections.groupProperty( " age " )); projectionList.add(Projections.rowCount()); Criteria criteria = session.createCriteria(TUser. class ); criteria.setProjection(projectionList); List list criteria.list();
Hibernate 属性查询
有时候我们并不需要获取完整的实体对象,如在一个下拉框中显示用户名,此时我们需要的数据仅仅是实体对象的某个属性(库表记录中的某个字段信息)。同样通过HQL我们也可以简单地做到这一点
List list = session.criteriaQuery( " select user.name from TUser user " ).list(); Iterator it = list.iterator(); while (is.hashNext){ System.out.println(it.next); }
HQL "select user.name from TUser user" 指定了我们只需要获取TUser对象的name属性(也就是T_User表的name字段)。此时返回的是List数据结构中,每个条目都是一个Stirng类型的那么数据(而非TUser对象)
List list = session.criteriaQuery("select user.name,user.age from TUser user").list(); Iterator it =list.iterator(); while(is.hashNext){ Object[] obj=(Object[])it.next System.out.println(obj[0]); System.out.println(obj[1]); }
HQL select user.name,user.age from TUser user 表明我们需要读取name和age属性的内容,而此时,返回的list数据结构中,每个条目都是一个对象数据(Objcet[]),其中一次包含了我们所获得的属性数据
如果觉得返回数组的方式不够符合面向对象的风格,我们可以通过HQL中动态构造对象实例的方法对这些平面化的数据进行封装。
List list = session.criteriaQuery( " select new TUser(user.name,user.age) from TUser user " ).list(); Iterator it = list.iterator(); while (is.hashNext){ TUser user = (TUser)it.next System.out.println(user.getName()); }
实体更新与删除
Hibernate 2中查询及更新
TUser user = (TUser)session.get(TUser. class , new Integer( 1 )); user.setAge( new Integer( 18 )); session.save(user);
以上代码完成ID=1的用户数据更行,那么,如果我们需要将库表中所有的用户的年龄置为18,该如何操作呢,别无它法,我们只有搜先利用HQL “from TUser ”查询出所有的实体,设置年属性后在逐一保存
Hibernate3 HQL提供了更为灵活的便捷的实现方式(bulkdelete/update)
Transaction tx = session.beginTranscation(); String sql = " update TUser set age=18 where id=1 " ; Query query = session.createQuery(hql); query.executeUpdate(); tx.commit();
HQL delte子句使用
Transaction tx = session。beginTranscation(); String sql = " delete TUser where id=1 " ; Query query = session.createQuery(hql); int ret = query.executeUpdate(); System.out.println(ret); tx.commit();
参数绑定
String sql="from TUser user where user.age>"+age;
编码更加凌乱,可读性降低、难以进行性能优化、引入额外的安全风行
我们应该采用
session.find("from TUser user where user.name=?","Erica",Hibernate.STRING);
多参数的情况
Object[] args = new Object[]{ " Erica " , new Integer( 20 )}; Type[] types = new Type[]{Hibernate.STRING,Hibernate.INTEGER}; session.find( " from TUser user where user.name=? and user.age>? " ,args,types);
或者通过Query接口进行参数填充
Query query = session.createQuery( " from TUser user where user.name=? and user.age>? " ); query.setString( 0 , " Erica " ); quer.setInteger( 1 , 20 );
占位符
String sql = from TUser user where user.name = :name and user.age > :age " ; Query query = session.createQuery(hql); query.setParameter( " name " , " Erica " ); query.setParameter( " age " , 18 );