- 浏览: 6359421 次
- 性别:
- 来自: 一片神奇的土地
文章分类
- 全部博客 (745)
- JQuery (25)
- JS (33)
- 数据库 (59)
- Java基础 (56)
- JSON (8)
- XML (8)
- ireport (7)
- 设计模式 (10)
- 心情 (14)
- freemarker (1)
- 问题 (15)
- powerdesigner (2)
- CSS (15)
- DWR (4)
- tomcat (16)
- Hibernate (12)
- Oracle (7)
- Struts (7)
- Spring (34)
- JSP (23)
- 需学习 (64)
- 工具类库 (63)
- Maven (14)
- 笔试题 (34)
- 源码学习 (31)
- 多线程 (39)
- Android (32)
- 缓存 (20)
- SpringMVC (14)
- jQueryEasyUi (12)
- webservice-RPC (13)
- ant (1)
- ASP.NET (10)
- 正则表达式 (3)
- Linux (15)
- JBoss (1)
- EJB (3)
- UML (2)
- JMS (3)
- Flex (8)
- JSTL (2)
- 批处理 (5)
- JVM (16)
- 【工具】 (16)
- 数据结构 (29)
- HTTP/TCP/Socket (18)
- 微信 (1)
- tomcat源码学习 (15)
- Python (30)
- 主机 (2)
- 设计与架构 (19)
- thrift-RPC (2)
- nginx (6)
- 微信小程序 (0)
- 分布式+集群 (12)
- IO (1)
- 消息队列 (4)
- 存储过程 (8)
- redis (9)
- zookeeper (5)
- 海量数据 (5)
最新评论
-
360pluse:
技术更新,战术升级!Python爬虫案例实战从零开始一站通网盘 ...
Python爬虫实战:Scrapy豆瓣电影爬取 -
18335864773:
推荐用 pageoffice 组件生成 word 文件。
JAVA生成WORD工具类 -
jjhe369:
LISTD_ONE 写道起始地址为163.135.0.1 结束 ...
IP地址与CIDR -
baojunhu99:
private final int POOL_SIZE = 5 ...
使用CompletionService获取多线程返回值 -
LovingBaby:
胡说,javascript 运行时是单线程的,event lo ...
Ajax请求是否可以实现同步
在常规的Web编程中,有大量的动态条件查询,即用户在网页上面自由选择某些条件,程序根据用户的选择条件,动态生成SQL语句,进行查询。
针对这种需求,对于分层应用程序来说,Web层需要传递一个查询的条件列表给业务层对象,业务层对象获得这个条件列表之后,然后依次取出条件,构造查询语句。这里的一个难点是条件列表用什么来构造?传统上使用Map,但是这种方式缺陷很大,Map可以传递的信息非常有限,只能传递name和value,无法传递究竟要做怎样的条件运算,究竟是大于,小于,like,还是其它的什么,业务层对象必须确切掌握每条entry的隐含条件。因此一旦隐含条件改变,业务层对象的查询构造算法必须相应修改,但是这种查询条件的改变是隐式约定的,而不是程序代码约束的,因此非常容易出错。
DetachedCriteria可以解决这个问题,即在web层,程序员使用DetachedCriteria来构造查询条件,然后将这个 DetachedCriteria作为方法调用参数传递给业务层对象。而业务层对象获得DetachedCriteria之后,可以在session范围内直接构造Criteria,进行查询。就此,查询语句的构造完全被搬离到web层实现,而业务层则只负责完成持久化和查询的封装即可,与查询条件构造完全解耦,非常完美!
Criteria 和 DetachedCriteria 的主要区别在于创建的形式不一样, Criteria 是在线的,所以它是由 Hibernate Session 进行创建的;而 DetachedCriteria 是离线的,创建时无需Session
,DetachedCriteria 提供了 2 个静态方法 forClass(Class) 或 forEntityName(Name)进行DetachedCriteria 实例的创建。
Spring 的框架提供了getHibernateTemplate().findByCriteria(detachedCriteria) 方法可以很方便地根据DetachedCriteria 来返回查询结果。
Criteria:
查詢User表格中的所有資料:
Criteria criteria = session.createCriteria(User.class);
// 查詢user所有欄位
List users = criteria.list();
Iterator iterator = users.iterator();
while(iterator.hasNext()) {
User user = (User) iterator.next();
System.out.println(user.getId() + user.getName());
}
Hibernate实际上使用以下的SQL來查詢:
select this_.id as id0_, this_.name as name0_0_ from user this_
Criteria只是个容器,如果想要設定查詢條件,則要使用add()方法加入Restrictions的条件限制
,例如查詢age大於20且小於40的資料:
Criteria criteria = session.createCriteria(User.class);
criteria.add(Restrictions.gt("age", new Integer(20)));
criteria.add(Restrictions.lt("age", new Integer(40)));
List users = criteria.list();
您也可以使用逻辑組合來进行查詢,例如結合age等於(eq)20或(or)age為空(isNull)的條件:
Criteria criteria = session.createCriteria(User.class);
criteria.add(Restrictions.or(
Restrictions.eq("age", new Integer(20)),
Restrictions.isNull("age")
));
List users = criteria.list();
DetachedCriteria的关联查询:
假设要通过stuName查询一个学生Student记录,可以如下:
DetachedCriteria dc = DetachedCriteria.forClass(Student.class);
dc.add(Restrictions.like("stuName", stuName, MatchMode.ANYWHERE));
如果要通过Student的Team的teamName查询一个Student记录,很多人都会这么写:
DetachedCriteria dc = DetachedCriteria.forClass(Student.class);
dc.add(Restrictions.like("team.teamName", teamName, MatchMode.ANYWHERE));
遗憾的是上述程序报错,说是在Student中找不到team.teamName属性,这是可以理解的。那么如何通过teamName查找Student呢?
可以这么写:
DetachedCriteria dc = DetachedCriteria.forClass(Student.class);
dc.createAlias("team", "t");
dc.add(Restrictions.like("t.teamName", teamName, MatchMode.ANYWHERE));
没错,就是要先建立team的引用,才能用team导航到teamName
。
这里有一个特殊情况,如果是对引用对象的id查询,则可以不用建立引用,也就是可以不调用createAlias()语句,如下所示:
DetachedCriteria dc = DetachedCriteria.forClass(Student.class);
dc.add(Restrictions.like("team.id", teamId, MatchMode.ANYWHERE));
据我个人的经验,team后只能跟其主键属性,比较其他属性要用别名。此主键属性可以用“id”字符来指代,也可以用team的主键属性来指代。换句话
说,我的Student类的类主键“stuId”,不管是在HQL还是在QBC中,都可以用stu.id来指代stu.stuId。在这里可以看出
“id”字符的特殊性。上述是个人观点,并未得到确实的证实。
DetachedCriteria:
例子1:如果每个美女都有自己的客户资源(不要想歪了!),那么需要查询拥有客户Gates的美女怎么办?
两种方法:
1:
DetachedCriteria beautyCriteria = DetachedCriteria.forClass(Beauty.class).createCriteria("customers");
beautyCriteria.add(Restrictions.eq("name", "Gates")):
2:
DetachedCriteria beautyCriteria = DetachedCriteria.forClass(Beauty.class).createAlias("customers", "c");
beautyCriteria.add(Restrictions.eq("c.name", "Gates")):
接着有了新的要求,年纪太大的美女不要,还是查找拥有客户Gates的,条件如下:
DetachedCriteria beautyCriteria = DetachedCriteria.forClass(Beauty.class, "b").;
DetachedCriteria customerCriteria = beautyCriteria.createAlias("customers", c");
beautyCriteria.add(Restrictions.le("b.age", new Long(20))):
customerCriteria.add(Restrictions.eq("c.name", "Gates")):
关于Criteria更详细的资料,Hibernate的源代码和测试是最好的文档。
Criteria的缺点?DBA很生气,后果很严重。
例子2:
Department和Employee是一对多关联,查询条件为:
名称是“department”开发部门;
部门里面的雇员年龄大于20岁;
DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Department.class);
detachedCriteria.add(Restrictions.eq("name", "department"))
.createAlias("employees", "e")
.add(Restrictions.gt(("e.age"), new Integer(20)));
List list = this.getHibernateTemplate().findByCriteria(detachedCriteria);
detachedCriteria.add(Expression.like("citycode", markuplayer8.getCitycode(),MatchMode.ANYWHERE));
SQL:
if(startdate!=null && !startdate.equals("") && enddate!=null && !enddate.equals("")){ StringBuffer sb = new StringBuffer(); sb.append("enddate >='" + enddate + "' and '"+startdate+"' <= startdate"); detachedCriteria.add(Expression.sql(sb.toString())); } List<Markuplayer8> markuplayerList = this.getHibernateTemplate().findByCriteria(detachedCriteria);
重要:
http://dev.yesky.com/241/2033241.shtml
http://www.tup.com.cn/Resource/tsyz/027541-01.txt
http://www.blogjava.net/hilor/archive/2007/09/14/145172.html
很全的例子:http://blog.csdn.net/kjfcpua/archive/2009/06/21/4287248.aspx
org.hibernate.criterion.Restrictions类 定义了获得某些内置Criterion类型的工厂方法。
List cats = sess.createCriteria(Cat.class)
.add( Restrictions.like("name", "Fritz%") )
.add( Restrictions.between("weight", minWeight, maxWeight) )
.list();
约束可以按逻辑分组。
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提供了相当多的内置criterion类型(Restrictions 子类), 但是尤其有用的是可以允许
你直接使用SQL。
List cats = sess.createCriteria(Cat.class)
.add( Restrictions.sql("lower({alias}.name) like lower(?)", "Fritz%",
Hibernate.STRING) )
.list();
{alias}占位符应当被替换为被查询实体的列别名。
Property实例是获得一个条件的另外一种途径。你可以通过调用Property.forName() 创建一个
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. 结果集排序
你可以使用org.hibernate.criterion.Order来为查询结果排序。
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()非常容易的在互相关联的实体间建立 约束。
List cats = sess.createCriteria(Cat.class)
.add( Restrictions.like("name", "F%")
.createCriteria("kittens")
.add( Restrictions.like("name", "F%")
.list();
注意第二个 createCriteria()返回一个新的 Criteria实例,该实例引用kittens 集合中的元素。
接下来,替换形态在某些情况下也是很有用的。
List cats = sess.createCriteria(Cat.class)
.createAlias("kittens", "kt")
.createAlias("mate", "mt")
.add( Restrictions.eqProperty("kt.name", "mt.name") )
.list();
(createAlias()并不创建一个新的 Criteria实例。)
Cat实例所保存的之前两次查询所返回的kittens集合是 没有被条件预过滤的。如果你希望只获得
符合条件的kittens, 你必须使用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();
这个查询可以通过外连接抓取mate和kittens。
6. 查询示例
org.hibernate.criterion.Example类允许你通过一个给定实例 构建一个条件查询。
Cat cat = new Cat();
cat.setSex('F');
cat.setColor(Color.BLACK);
List results = session.createCriteria(Cat.class)
.add( Example.create(cat) )
.list();
版本属性、标识符和关联被忽略。默认情况下值为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在关联对象上放置条件。
List results = session.createCriteria(Cat.class)
.add( Example.create(cat) )
.createCriteria("mate")
.add( Example.create( cat.getMate() ) )
.list();
7. 投影(Projections)、聚合(aggregation)和分组(grouping)
org.hibernate.criterion.Projections是 Projection 的实例工厂。我们通过调用
setProjection()应用投影到一个查询。
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" 。某些投影类型就是被定义为 分组投影,他
们也出现在SQL的group by子句中。
可以选择把一个别名指派给一个投影,这样可以使投影值被约束或排序所引用。下面是两种不同的
实现方式:
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实例中。简而言之,
当你添加一个投影到一个投影列表中时 你可以为它指定一个别名:
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()来表示投影:
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)查询和子查询
DetachedCriteria类使你在一个session范围之外创建一个查询,并且可以使用任意的 Session来
执行它。
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也可以用以表示子查询。条件实例包含子查询可以通过 Subqueries或者
Property获得。
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();
相互关联的子查询也是有可能的:
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();
发表评论
-
strust_spring_hibernate的优缺点
2014-10-08 09:41 2761struts框架具有组件的模块化,灵活性和重用性的优点,同时 ... -
Hibernate实现原理 与 缺点
2014-09-26 17:55 10412Hibernate是怎样实现呢?主要是依据反射机制。 ... -
hibernate报错异常总结
2011-06-09 12:22 103251、A collection with cascade=&qu ... -
[转]hibernate的Hql总结
2011-05-27 11:31 17151. 查询整个映射对象所有字段 //直接from查询出来 ... -
一对多里对 set 的排序
2011-05-17 10:28 3736一对多里面对 set 的排序,建议采用以下办法: ... -
[转]使用hibernate所遇到的问题总结
2011-03-26 10:11 741、catalog 我用myEclipse开发,基本上P ... -
hibernate中日期问题+日期查询
2011-03-07 18:12 5191Java类中使用Date类型,而其映射文件使用java.sql ... -
小结Hibernate的查询方式(6种)
2011-03-05 13:30 20561、 get() and load() sess ... -
Hibernate底层数据库操作函数BaseDao+具体实例
2011-03-05 13:13 12510List ls = this.getHibernateTe ... -
Hibernate缓存机制
2011-02-21 11:35 1987Hibernate 中提供了两级Cache,第一级别的 ... -
jdbcTemplate.getAllUser
2010-12-22 11:30 871. public List<TaoBaoStore ... -
【需学习】Annotation+表中的父子关系
2010-11-18 17:10 74使用 Annotation 并对 DAO 层封装具有分 ... -
Hibernate习题总结!
2010-11-11 10:50 156一、Hibernate工作原理: ... -
Hiberante中多表关联!
2010-11-09 15:52 1767一、多对一进行关联 (多个学生对应同一间宿舍)---学生 ... -
Hibernate学习笔记!
2010-11-09 10:24 2009Hibernate 是一个开放源代码的对象关系映射框架,它对 ...
相关推荐
使用 DetachedCriteria 可以很方便地根据查询条件来返回查询结果,Spring 框架提供了 `getHibernateTemplate().findByCriteria(detachedCriteria)` 方法来实现这一点。 Criteria 和 DetachedCriteria 均可使用 ...
在DetachedCriteria中定义的查询条件可以在稍后的时间点附加到Session上执行,这使得查询可以脱离当前的Session状态,因此得名“Detached”。这种特性在处理复杂的、跨多个事务的查询时非常有用,同时也可以避免因长...
DetachedCriteria 是 Hibernate 中的一种离线查询对象,它可以在不依赖 Session 的情况下生成动态 SQL 语句并进行查询。下面是 DetachedCriteria 查询的详细知识点: 创建 DetachedCriteria 对象 DetachedCriteria...
《Hibernate查询条件查询详解》 Hibernate作为Java领域中广受欢迎的对象关系映射(ORM)框架,极大地简化了数据库操作。其强大的查询能力是其核心功能之一。本篇将深入探讨Hibernate的条件查询,帮助开发者更好地...
在实际开发中,Hibernate Criteria查询提供了很大的便利性,尤其是在处理动态查询和复杂查询时。通过熟练掌握Criteria API,可以编写出更简洁、更易于维护的代码。希望这份资料能帮助你更好地理解和运用Hibernate的...
在Java的持久化框架Hibernate中,DetachedCriteria是一个强大的查询工具,它允许我们在不与Session交互的情况下构建查询条件。然而,DetachedCriteria在处理复杂的关联查询,尤其是涉及到表连接(JOIN)时,可能存在...
Criteria API提供了一种更为灵活和强大的查询方式,它基于标准的Java对象模型来构建查询条件,支持动态创建查询条件。 **特点:** - **面向对象:** Criteria API完全基于对象,这使得它更加灵活和强大。 - **动态...
在这个“springMVC+hibernate的条件查询加分页的demo”中,我们将探讨如何结合这两个框架实现动态的条件查询和分页功能。 首先,让我们了解一下SpringMVC中的条件查询。在SpringMVC中,通常通过Controller层接收...
同时,HQL支持动态查询,可以根据参数动态构造查询语句,适合于复杂或动态的查询需求。 - **基本结构**:HQL查询通常以`from`开始,后面跟着实体类的名称。可以使用`select`指定返回的结果,`where`后跟查询条件,`...
同时,Hibernate还提供了Criteria API,它是QBC的一部分,提供了更多的动态查询功能,可以组合多个条件,甚至可以与DetachedCriteria结合,实现更复杂的查询逻辑。 总结来说,Java_Hibernate中的QBC和HQL各有优势和...
如果你希望在不打开Session的情况下构建查询条件,可以使用DetachedCriteria: ```java DetachedCriteria detached = DetachedCriteria.forClass(User.class); detached.setProjection(Projections.property(...
3. **平台无关**:由于HQL是基于Hibernate框架的查询语言,因此不受特定数据库的影响,可以在不同的数据库平台上无缝迁移。 4. **灵活性**:HQL支持多种查询方式,包括简单查询、复杂查询、联接查询等。 ### HQL的...
5. **多态查询的实现**:Hibernate支持使用`DetachedCriteria`或`Criteria` API来进行多态查询,通过`createCriteria()`方法指定父类,并使用`add(Restrictions.in("property", values))`等方法来限制查询条件。...
7. **Criteria查询**:除了HQL,Hibernate还提供了Criteria API,这是一种动态构建查询的方式,可以根据条件构建查询,更加灵活。 8. ** Criteria API的DetachedCriteria**:DetachedCriteria允许在不打开Session的...
Criteria API则提供了一种更加面向对象的查询方式,它允许我们构建查询条件并动态地组合它们。以下是如何使用Criteria API来获取所有用户: ```java Session session = HibernateUtil.getSessionFactory()....
`DetachedCriteria` 是 Hibernate 提供的一种灵活且强大的查询机制,它允许你在脱离 Session 的情况下构建复杂的查询标准,这意味着你可以提前构建查询标准,然后在任何地方执行查询,而无需关心当前是否有 Session...
Criteria API的优点在于代码可读性高,且支持动态构建查询条件。 ### 三、QBC(Query By Example) QBC是一种基于实例的查询方式,它允许你通过一个对象实例来定义查询条件。以下是一个使用QBC的例子: ```java ...
`org.hibernate.criterion`包中的类如`DetachedCriteria`、`Expression`等用于构建这些条件。源码中,`CriteriaQueryTranslator`负责将Criteria API表达式转化为SQL。 最后,JPA的JPQL(Java Persistence Query ...
在Java持久层框架Hibernate中,Criteria API是一种动态构建SQL查询的方法,它允许开发者在运行时构建查询,提供了更面向对象的查询方式。本篇将详细阐述Hibernate Criteria API的使用。 首先,Criteria API由...
在复杂的查询场景下,可以使用DetachedCriteria来预定义查询条件,然后在需要时再与其他查询组合使用。 5. **命名查询(Named Queries)**: 如果某些查询模式经常被使用,可以定义命名查询,将其写入XML映射文件...