Hibernate Criterion

Hibernate Criterion

大家好,又见面了,我是全栈君,祝每个程序员都可以多学几门语言。

在查询方法设计上能够灵活的依据Criteria的特点来方便地进行查询条件的组装.
Hibernate设计了CriteriaSpecification作为Criteria的父接口,以下提供了Criteria和DetachedCriteria.

Criteria和DetachedCriteria的主要差别在于创建的形式不一样,Criteria是在线的,所以它是由HibernateSession进行创建的;
而DetachedCriteria是离线的,创建时无需Session,DetachedCriteria提供了2个静态方法forClass(Class)或forEntityName(Name)进行DetachedCriteria实例的创建.
Spring的框架提供了getHibernateTemplate().findByCriteria(detachedCriteria)方法,能够非常方便地依据DetachedCriteria来返回查询结果.
Criteria和DetachedCriteria均可使用Criterion和Projection设置查询条件.能够设置FetchMode(联合查询抓取的模式),设置排序方式.
对于Criteria还能够设置FlushModel(冲刷Session的方式)和LockMode(数据库锁模式).

以下对Criterion和Projection进行具体说明.

Criterion是Criteria的查询条件.Criteria提供了add(Criterion criterion)方法来加入�查询条件.Criterion接口的主要实现包含:Example、Junction和SimpleExpression.
而Junction的实际使用是它的两个子类conjunction和disjunction,各自是使用AND和OR操作符进行来联结查询条件集合.
Criterion的实例能够通过Restrictions工具类来创建,Restrictions提供了大量的静态方法;如:eq(等于)、ge(大于等于)、between等来方法的创建Criterion查询条件(SimpleExpression实例).
除此之外,Restrictions还提供了方法来创建conjunction和disjunction实例,通过往该实例的add(Criteria)方法来添加�查询条件形成一个查询条件集合.

至于Example的创建有所不同,Example本身提供了一个静态方法create(Object entity),即依据一个对象(实际使用中通常是映射到数据库的对象)来创建.然后能够设置一些过滤条件:
Example exampleUser = Example.create(u)
.ignoreCase() // 忽略大写和小写
.enableLike(MatchMode.ANYWHERE); // 对String类型的属性,不管在那里值在那里都匹配.相当于%value% Project主要是让Criteria能够进行报表查询,并能够实现分组.

Project主要有SimpleProjection、ProjectionList和Property三个实现.
当中SimpleProjection和ProjectionList的实例化是由内建的Projections来完毕,如提供的avg、count、max、min、sum能够让开发人员非常easy对某个字段进行统计查询.
Property是对某个字段进行查询条件的设置,如通过Porperty.forName(“color”).in(new String[]{“black”,”red”,”write”});则能够创建一个Project实例.
通过criteria的add(Project)方法添�到查询条件中去.使用Criteria进行查询,主要要清晰的是Hibernate提供了那些类和方法来满足开发中查询条件的创建和组装,以下介绍几种使用方法:

1.创建一个Criteria实例
org.hibernate.Criteria接口表示特定持久类的一个查询.Session是Criteria实例的工厂.
Criteria crit = sess.createCriteria(Cat.class);
crit.setMaxResults(50);
List cats = crit.list();

2.限制结果集内容
一个单独的查询条件是org.hibernate.criterion.Criterion接口的一个实例.
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()很easy的在互相关联的实体间建立约束.
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();

补充:
criteria.add(Expression.eq(“status”,new Integer(status)));
criteria.add(Expression.in(“status”, optParm.getQueryStatus()));

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/118327.html原文链接:https://javaforall.net

(0)
上一篇 2021年12月7日 下午5:00
下一篇 2021年12月7日 下午6:00


相关推荐

  • html.dropdownlistfor_html按钮样式

    html.dropdownlistfor_html按钮样式//获取直属父级列表varparents=_MemberEditDTOService.GetParents();varparentsItems=parents.Result.Select(s=>newSelectListItem(){Text=s.MemberName,Value=((int)s.Id).ToString()}).ToList();//parents…

    2022年8月31日
    5
  • JavaBean 的小知识点

    推荐:http://www.cnblogs.com/roucheng/p/3504465.html

    2021年12月26日
    47
  • 读取位置时发生访问冲突0xC0000005_应用程序异常0xc0000409

    读取位置时发生访问冲突0xC0000005_应用程序异常0xc0000409转首先排除一种小概率事件就是系统冲突导致的,比如系统盘目录存在类似的第三方库文件,程序运行将崩溃,并报错0xC0000005:读取位置0x00000000时发生访问冲突。上面的意思就是你吧值付给了不该赋给的变量,或者说你把值付给了不能付给的变量(或者常量)(1)最简单也最直接的错误可能就是scanf()的问题,我们都知道输入的时候都是scanf(“%格式”,&变量),那…

    2022年10月3日
    5
  • android开发冷启动和热启动的区别,android 冷启动和热启动

    android开发冷启动和热启动的区别,android 冷启动和热启动一 什么是冷启动 热启动 冷启动 在启动应用时 系统中没有该应用的进程 这时系统会创建一个新的进程分配给该应用 热启动 在启动应用时 系统中已有该应用的进程 例 按 back 键 home 键 应用虽然会退出 但是该应用的进程还是保留在后台 二 冷启动 热启动的区别冷启动 系统没有该应用的进程 需要创建一个新的进程分配给应用 所以会先创建和初始化 Application 类 再创建和初始化 MainActi

    2026年3月19日
    2
  • CCIE理论-第二篇-SDN-FabricPath技术

    CCIE理论-第二篇-SDN-FabricPath技术CCIE 理论 第二篇 FabricPath 技术首先 什么是 FabricPath 呢 这个东东是思科的私有技术 而且只能在 Nexus 系列设备上使用例如 N5K N6K N7K N9K 都是支持的但是 这个东西东西 是完完全全纯数据中心使用的顺带提一下 其实基本上 SDN 都是用于数据中心上的有一个点不得不承认 思科的私有化的东西 永远是比公有化的东东的牛逼的比如 CDP 就是比 LLDP 强比如 EIGRP 就是比 OSPF 强之前在 vxlan 提过的 overlay 网络 同等于 fabric 网络什么是 overly

    2026年3月20日
    2
  • Hello, Webpack!

    Hello, Webpack!

    2022年3月13日
    44

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号