Hibernate-Criteria接口

Hibernate Criteria简介

一、Criteria接口的用途:

  • 设计上可以灵活的根据criteria的特点进行查询条件的组装。

  • CriteriaSpecification 接口是 Criteria 接口和 DetachedCriteria 接口的父接口。

  • DetachedCriteria 接口和 Criteria 接口的主要区别在于:

    1. Criteria 是在线的,所以他由Hibernate Session进行创建;而DetachedCriteria 是离线的,创建时无需Session,他自己提供了两个静态方法:forClass(Class) 、forEntityName(Name),来进行实例的创建。
    2. Spring中提供了getHibernateTemplate().findByCriteria(DetachedCriteria)可以很方便的根据DetachedCriteria来返回查询结果。
      </br>
  • Criteria接口特性:

    1. 他们均可以通过Criterion 和 Projection 来设置查询条件。可以设置 FetchModel(联合查询抓取的模式)来设置排序方式;对于Criteria可以设置FlushModel(冲刷Session的方式)和LockModel(数据库锁模式)。
    2. Criterion是Criteria的查询条件,Criteria提供了add(Criterion criterion)方法来添加查询条件。
    3. Criterion接口的主要实现类主要包括:Example、Junction、SimpleExpression。而Junction实际使用是他的两个子类Conjunction、Disjunctive,分别使用 AND 和 OR 操作符来链接查询条件集合。
    4. Criteria的实例可以通过Restrictions工具类累创建,Restrictions提供了大量的静态方法,eg:eq(等于)、ge(大于等于)、between等方法来创建Criterion 查询条件(SimpleExpression实例),除此之外,Restrictions还提供了Conjunction 和 Disjunction创建的方法,通过往该实例的add(Criteria criteria)方法来添加出巡条件,形成一个查询条件集合。
    5. Example的创建有所不同,Example本身提供了create(Object entity)静态方法,即根据一个对象来创建(实际使用中一般是映射到数据库对象),然后可以添加一些过滤条件。 Example example = Example.create(u).ignoreCase().enableLike(MatchMode.ANYWHERE); //忽略大小写,以及对于String类型的属性进行模糊匹配
    6. Project主要是让Criteria能够进行报表查询,并可以进行分组。Project主要有SimpleProject、ProjectionList、Property三个实现类,其中SimpleProject、ProjectionList的实例化是由内建的Projections来完成。如:提供avg、count、max、min、sum等,让开发者能够很容易的对某字段进行统计查询。Property是对某个字段进行查询条件的设置,如:Property.forName("color‘).in(new String[]{"black","red","write"});则可以创建一个Property实例,通过Criteria的add(Project)方法加入到查询条件中去。

</br>

二、Criteria查询接口的用法:

</br>

  • 1、Criteria无条件查询

无条件查询,即不输入任何查询条件,此时,会将表中的所有的数据都查询出来
org.hibernate.Criteria接口表示一个特定持久类的查询,Session是Criteria接口的实例工厂。


  • 建表语句
create table login
(
  username   varchar2(32) primary key,
  password   varchar2(32) not null ,
  age      number(3)
);
insert into login
select '张三','123456',21 from dual union
select 'Tom','123123',34 from dual union
select 'Jack','12345678',34 from dual union
select '李四','qwerty',23 from dual;         
commit;  
  • Hibernate.cfg.xml
<?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.url">
        jdbc:oracle:thin:@127.0.0.1:1521:XE
    </property>
    <!-- 连接数据库的驱动 -->
    <property name="connection.driver_class">
        oracle.jdbc.driver.OracleDriver
    </property>
    <!-- 连接数据库的用户名和密码 -->
    <property name="connection.username">SYSTEM</property>
    <property name="connection.password">SYSTEM</property>
    <!-- 连接数据库用的方言 -->
    <property name="dialect">
        org.hibernate.dialect.Oracle10gDialect
    </property>
    
    <!--第二部分: Hibernate框架的基本属性 -->
    
    <property name="show_sql">true</property>
    <property name="format_sql">true</property>
    <!--自动建表   或者 create 删除再创建,只删除做了映射的-->
    <mapping resource="criteria/unconditional/bean/Login.hbm.xml" />

</session-factory>

</hibernate-configuration>  
  • Bean持久类
package criteria.unconditional.bean;

import java.io.Serializable;

public class Login implements Serializable{

    private static final long serialVersionUID = 1L;
    
    private String username;
    private String password;
    private int age;
    
    public Login(){
        
    }
    
    public Login(String username, String password) {
        this.username = username;
        this.password = password;
    }
    
    public Login(String username, String password, int age) {
        this.username = username;
        this.password = password;
        this.age = age;
    }
    
    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    
}

  • Bean.hbm.xml持久化配置类
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
  <class name="criteria.unconditional.bean.Login" table="LOGIN" schema="ROOT">
    <id name="username" type="java.lang.String">
      <column name="USERNAME" length="32" />
      <generator class="assigned" />
    </id>
    <property name="password" type="java.lang.String">
      <column name="PASSWORD" length="32" not-null="true" />
    </property>
    <property name="age" type="java.lang.Integer">
      <column name="AGE" precision="3" scale="0" />
    </property>
  </class>
</hibernate-mapping>

  • 测试类
package criteria.unconditional.dao;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

import criteria.unconditional.bean.Login;

/**
 * 无条件查询测试类
 * 
 * @author wxf
 *
 */
public class Demo {
    /**
     * Criteria无查询条件查询所有
     */
    public static void main(String[] args) {
        // 声明一个集合用来接收结果
        List<Login> result = null;
        // 声明SessionFactory
        SessionFactory factory = null;
        // 声明Session
        Session session = null;
        // 初始化以上对象
        try {
            factory = new Configuration().configure().buildSessionFactory();
            session = factory.openSession();
            // 声明Criteria对象传入一个持久化类对象类型
            Criteria criteria = session.createCriteria(Login.class);
            // 查询使用list方法
            result = criteria.list();
        } catch (HibernateException e) {
            e.printStackTrace();
        } finally {
            session.close();
            factory.close();
        }
        // 输出结果
        for (Login login : result) {
            System.out.println("用户名:" + login.getUsername() + "   密码:" + login.getPassword() + "   年龄:" + login.getAge());
        }
    }
}

  • 查询语句
  select
    this_.USERNAME as USERNAME0_0_,
    this_.PASSWORD as PASSWORD0_0_,
    this_.AGE as AGE0_0_ 
  from
    ROOT.LOGIN this_

</br>

  • 2、Criteria单条件查询

加入一个username作为查询条件
Restrictions提供了大量的静态方法,eg:eq(等于)、ge(大于等于)、between等方法来创建Criterion 查询条件(SimpleExpression实例)


  • 测试类
package criteria.unconditional.dao;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.criterion.Restrictions;

import criteria.unconditional.bean.Login;

/**
 * 单条件查询 添加username作为查询条件
 * 
 * @author wxf
 *
 */
public class Demo1 {

    /**
     * Criteria无查询条件查询所有
     */
    public static void main(String[] args) {
        // 声明一个集合用来接收结果
        List<Login> result = null;
        // 声明SessionFactory
        SessionFactory factory = null;
        // 声明Session
        Session session = null;
        // 初始化以上对象
        try {
            factory = new Configuration().configure().buildSessionFactory();
            session = factory.openSession();
            // 声明Criteria对象传入一个持久化类对象类型
            Criteria criteria = session.createCriteria(Login.class);

            // 添加查询条件 Restrictions.eq是等于的意思,2个参数,第一个为持久化类的属性,第2个为比较的参数值
            criteria.add(Restrictions.eq("username", "Tom"));

            // 查询使用list方法
            result = criteria.list();
        } catch (HibernateException e) {
            e.printStackTrace();
        } finally {
            session.close();
            factory.close();
        }
        // 输出结果
        for (Login login : result) {
            System.out.println("用户名:" + login.getUsername() + "   密码:" + login.getPassword() + "   年龄:" + login.getAge());
        }
    }
}

添加查询条件 Restrictions.eq是等于的意思,2个参数,第一个为持久化类的属性,第2个为比较的参数值
criteria.add(Restrictions.
eq(
"username",
"Tom"));

  • 查询语句
select this_.USERNAME as USERNAME0_0_, this_.PASSWORD as PASSWORD0_0_, this_.AGE as AGE0_0_ from ROOT.LOGIN this_ where this_.USERNAME=?

</br>

  • 3、Criteria多条件查询

查询 23 ~ 25 年龄段内的用户信息
Restrictions提供了大量的静态方法,eg:eq(等于)、ge(大于等于)、between等方法来创建Criterion 查询条件(SimpleExpression实例)


  • 测试类
//年龄小于等25岁的用户
criteria.add(Restrictions.le("age", 25));
//年龄大于等于23的用户
criteria.add(Restrictions.ge("age", 23));  
//或者直接用between查询  age >= 23 && age <= 25 的用户信息
criteria.add(Restrictions.between("age", 23, 25));  
  • 查询语句
select this_.USERNAME as USERNAME0_0_, this_.PASSWORD as PASSWORD0_0_, this_.AGE as AGE0_0_ from ROOT.LOGIN this_ where this_.AGE<=?  and this_.AGE>=?

select this_.USERNAME as USERNAME0_0_, this_.PASSWORD as PASSWORD0_0_, this_.AGE as AGE0_0_ from ROOT.LOGIN this_ where this_.AGE between ? and ?

</br>

  • 4、Criteria复合条件查询

查询 age = 23 && username 中含有‘李’字的用户
Restrictions提供了大量的静态方法,eg:eq(等于)、ge(大于等于)、between等方法来创建Criterion 查询条件(SimpleExpression实例)


  • 测试类
//查询年龄为23岁,或者名字里面有 李 字的用户
criteria.add(Restrictions.or(Restrictions.eq("age", 23),Restrictions.like("username", "%李%")));

//或者直接调用sql语句查询
criteria.add(Restrictions.sqlRestriction("age=23 or username like '%李%'"));  
  • 查询语句
select this_.USERNAME as USERNAME0_0_, this_.PASSWORD as PASSWORD0_0_, this_.AGE as AGE0_0_ from ROOT.LOGIN this_ where (  this_.AGE=?   or this_.USERNAME like ? )

select this_.USERNAME as USERNAME0_0_, this_.PASSWORD as PASSWORD0_0_, this_.AGE as AGE0_0_ from ROOT.LOGIN this_ where age=20 or username like '%李%'

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,686评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,668评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,160评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,736评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,847评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,043评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,129评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,872评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,318评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,645评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,777评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,861评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,589评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,687评论 2 351

推荐阅读更多精彩内容