Hibernate提供了完善的按条件(Query By Criteria, QBC)
org.hibernate.Criteria接口表示特定持久类的一个查询。
Criteria 代表一次查询
Criterion 代表一个查询条件。
Restrictions 产生查询条件的工具类。
Criterion 是 Criteria 的查询条件。Criteria 提供了 add(Criterion criterion) 方法来
1:添加查询条件。
Session是 Criteria实例的工厂。
Criteria criteria = sess.createCriteria(News.class);
List news = criteria.list();
2:限制结果集内容
一个单独的查询条件是org.hibernate.criterion.Criterion 接口的一个实例。org.hibernate.criterion.Restrictions类 定义了获得某些内置Criterion类型的工厂方法。Criterion 的实例可以通过 Restrictions 工具类来创建
List news = sess.createCriteria(News.class)
.add( Restrictions.like("title", "%fendou%") )
.add( Restrictions.between("id", 2, 8) )
.list();
Restrictions 提供了大量的静态
方法,如 eq (等于)、 ge (大于等于)、 between 等来方法的创建 Criterion 查询条件 ,通过往该实例的 add(Criteria) 方法来增加查询条件形成一个查询条件集合。
QL运算符 |
QBC运算符 |
含义 |
= |
Restrictions.eq() |
等于 |
<> |
Restrictions.not(Exprission.eq()) |
不等于 |
> |
Restrictions.gt() |
大于 |
>= |
Restrictions.ge() |
大于等于 |
< |
Restrictions.lt() |
小于 |
<= |
Restrictions.le() |
小于等于 |
is null |
Restrictions.isnull() |
等于空值 |
is not null |
Restrictions.isNotNull() |
非空值 |
like |
Restrictions.like() |
字符串模式匹配 |
and |
Restrictions.and() |
逻辑与 |
and |
Restrictions.conjunction() |
逻辑与 |
or |
Restrictions.or() |
逻辑或 |
or |
Restrictions.disjunction() |
逻辑或 |
not |
Restrictions.not() |
逻辑非 |
in(列表) |
Restrictions.in() |
等于列表中的某一个值 |
not in(列表) |
Restrictions.not(Restrictions.in()) |
不等于列表中任意一个值 |
between x and y |
Restrictions.between() |
闭区间xy中的任意值 |
not between x and y |
Restrictions.not(Restrictions..between()) |
小于值X或者大于值y |
3:结果集排序与分页
可以使用org.hibernate.criterion.Order来为查询结果排序
List news = sess.createCriteria(News.class)
.add( Restrictions.like("title", "%F%")
.addOrder( Order.desc("id") )
.setFirstResult(0)
.setMaxResults(20)
.list();
4: 使用createCriteria()非常容易的在互相关联的实体间建立约束
Criteria c=session.createCriteria(News.class);
news=c.add(Restrictions.in("id", new Long []{2l,4l}))
.add(Restrictions.like("title", "%今日%"))
.createCriteria("category")
.add(Restrictions.eq("id", 2))
.addOrder(Order.desc("id"))
.list();
5:投影(Projections)
org.hibernate.criterion.Projections是 Projection 的实例工厂。我们通过调用setProjection()应用投影到一个查询。
session=HibernateUtil.getSession();
Criteria c=session.createCriteria(News.class);
c.setProjection( Projections.projectionList()
.add( Projections.property("title"))
.add( Projections.property("category")));
news=c.list();
for(int i=0;i<news.size(); i++){
Object[] obj=(Object[])news.get(i);
System.out.println(obj[0]+"***"+obj[1]);
}
6:查询示例 (Query By Example, QBE)
org.hibernate.criterion.Example类允许你通过一个给定实例 构建一个条件查询(主要用于模糊查询)
List<News> news=new ArrayList<News>();
News exn=new News();
exn.setTitle("%今日%");
Example example=Example.create(exn);
example.enableLike();
Session session=HibernateUtil.getSession();
Criteria c=session.createCriteria(News.class);
c.add(example);
news=c.list();
Hibernate 中的原生SQL(Native SQL)查询
Hibernate3允许你使用手写的sql来完成所有的create,update,delete,和load操作(包括存储过程)
1:SQL查询是通过SQLQuery接口来控制的,它是通过调用Session.createSQLQuery()方法来获得
session=HibernateUtil.getSession();
news=session.createSQLQuery("select * from news_news n")
.addEntity(News.class).list();
addEntity()方法将SQL表的实体类联系起来,并且确定查询结果集的返回值形态。
2:原生的SQL查询可能返回一个简单的标量值或者一个标量和实体的结合体
session=HibernateUtil.getSession();
max=(Long)session.createSQLQuery("select max(n.n_id) as maxid from news_news n")
.addScalar("maxid",Hibernate.LONG)
.uniqueResult();
3:命名SQL查询
可以在映射文档中定义查询的名字,然后就可以象调用一个命名的HQL查询一样直接调用命名SQL查询.在这种情况下,我们不 需要调用addEntity()方法.
在po类的xml文件中命名一个sql
<sql-query name="sqlallnews">
<return class="com.fendou.domain.News"/>
select * from news_news n
</sql-query>
实现类调用:
news=session.getNamedQuery("sqlallnews")
4:使用存储过程来查询
Hibernate 3引入了对存储过程查询的支持. 存储过程必须返回一个结果集
如下面存储过程例子:
CREATE OR REPLACE FUNCTION selectAllnews
RETURN SYS_REFCURSOR
AS
st_cursor SYS_REFCURSOR;
BEGIN
OPEN st_cursor FOR
SELECT *
FROM news_news;
RETURN st_cursor;
END;
在Hibernate里要要使用这个查询,你需要通过命名查询来映射它.
<sql-query name="callselectAllnews" callable="true">
<return class="com.fendou.domain.News">
</return>
{ ? = call selectAllnews () }
</sql-query>
news=session.getNamedQuery("callselectAllnews")
.list();
对存储过程进行的查询无法使用setFirstResult()/setMaxResults()进行分页
Hibernate过滤数据
Hibernate3 提供了一种创新的方式来处理具有“显性(visibility)”规则的数据,那就是使用Hibernate filter。 Hibernate filter是全局有效的、具有名字、可以带参数的过滤器, 对于某个特定的Hibernate session您可以选择是否启用(或禁用)某个过滤器。过滤器条件相当于定义一个 非常类似于类和各种集合上的“where”属性的约束子句
1:定义一个过滤器
<hibernate-mapping/> 节点之内的<filter-def/>节点
<filter-def name="newsCategoryfilter">
<filter-param name="catid" type="int"/>
</filter-def>
2:定义好之后,就可以在某个类中要使用的属性下使用这个过滤器:
<filter name=" newsCategoryfilter " condition=":catid =c_id"/>
3:Session中默认是不启用过滤器的,必须通过Session.enabledFilter()方法显式的启用。 该方法返回被启用的Filter的实例
session.enableFilter("newsCategoryfilter ").setParameter("catid", 1);
String hql="from News";
Query query=session.createQuery(hql);
query.setFirstResult(0);
query.setMaxResults(5);
news=query.list();
通过使用过滤器可以定义常用的筛选规则,如果是临时的还是使用常规的查询比较好。