zoukankan      html  css  js  c++  java
  • 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来返回查询结果。

    • 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)方法加入到查询条件中去。

    ## 二、Criteria查询接口的用法:
    • 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_
    
    

    * **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=?
    

    * **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 ?
    

    * **4、Criteria复合条件查询**

    查询 age = 23 or 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 '%李%'
    

    三、Restrictions常用查询方法

    方法 说明
    Restrictions.eq() 等于 '='
    Restrictions.gt() 大于 '>'
    Restrictions.ge() 大于等于 '>='
    Restrictions.lt() 小于 '<'
    Restrictions.le() 小于等于 '<='
    Restrictions.between() sql中的between子句
    Restrictions.like() sql中的like子句
    Restrictions.in() sql中的in子句
    Restrictions.and() sql中的and子句
    Restrictions.or() sql中的or子句
    Restrictions.isNull() 非空
    • 基本用例
    //1.查询用户名为Tom的记录
    //criteria.add(Restrictions.eq("username", "Tom"));
    //2.查询年龄大于等于21同时小于等于25的记录
    //criteria.add(Restrictions.ge("age", 21));
    //criteria.add(Restrictions.le("age", 25));
    //between写法
    //criteria.add(Restrictions.between("age", 21, 25));
    //3.或者查询年龄=21或者名字中有李的记录
    //criteria.add(Restrictions.or(Restrictions.eq("age", 21), Restrictions.like("username", "%李%")));
    //sql写法
    //criteria.add(Restrictions.sqlRestriction("age=21 or username like '%李%'"));
    //4.年龄在21,23,25的记录
    //criteria.add(Restrictions.in("age", new Integer []{21,23,25}));
    //5.and用法
    criteria.add(Restrictions.and(Restrictions.ge("age", 23), Restrictions.like("username", "%T%")));
    

    # 四、Projections常用聚合函数
    方法 说明
    Projections.rowCount() 统计记录数
    Projections.avg() 统计平均值
    Projections.max() 统计最大值
    Projections.min() 统计最小值
    Projections.groupProperty() 进行分组
    Projections.count() 统计某一字段的非空记录数
    Projections.sum() 针对某一字段求和
    • 基本用例
    package demo;
    import java.util.Iterator;
    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.ProjectionList;
    import org.hibernate.criterion.Projections;
    import entity.Login;
    public class Demo3 {
      /**
       * 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);
        //加入查询条件
        //总记录数
        //criteria.setProjection(Projections.rowCount());
        //平均年龄
        //criteria.setProjection(Projections.avg("age"));
        //分组
        criteria.setProjection(Projections.groupProperty("username"));
        //查询使用list方法
        result=criteria.list();
        //System.out.println("平均年龄:"+result.iterator().next());
        //System.out.println("总记录数:"+result.iterator().next());
        Iterator iterator=result.iterator();
        while(iterator.hasNext()){
          System.out.println(iterator.next());
        }
        }catch(HibernateException e){
          e.printStackTrace();
        }finally{
          session.close();
          factory.close();
        }
      }
    }
    

    # 五、对查询结果进行排序

    使用order关键字来对查询结构排序
    criteria.addOrder(Order.desc("属性名称")); 降序
    criteria.addOrder(Order.asc("属性名称")); 升序

    //按年龄降序排序
    criteria.addOrder(Order.desc("age"));
    //按姓名升序排序
    criteria.addOrder(Order.asc("username"));
    

    六、分页显示

    • 基本用例
    package demo;
    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.Order;
    import org.hibernate.criterion.Restrictions;
    import entity.Login;
    public class Demo4 {
      /**
       * Criteria无查询条件查询所有
       */
      public static void main(String[] args) {
        //声明一个集合用来接收结果
        List<Login> result=null;
        //声明SessionFactory
        SessionFactory factory=null;
        //声明Session
        Session session=null;
        //当前页数第几页
        int pageIndex=1;
        //最大显示记录数
        int pageSize=2;
        //初始化以上对象
        try{
        factory=new Configuration().configure().buildSessionFactory();
        session=factory.openSession();
        //声明Criteria对象传入一个持久化类对象类型
        Criteria criteria=session.createCriteria(Login.class);
        //起始记录数
        criteria.setFirstResult((pageIndex-1)*pageSize);
        //每页显示最大记录数
        criteria.setMaxResults(pageSize);
        //查询使用list方法
        result=criteria.list();
        }catch(HibernateException e){
          e.printStackTrace();
        }finally{
          session.close();
          factory.close();
        }
        System.out.println("==========");
        //输出结果
        for (Login login : result) {
          System.out.println("用户名:"+login.getUsername()+"   密码:"+login.getPassword()+"   年龄:"+login.getAge());
        }
      }
    }
    

    # 七、关联
    • 基本用例
  • 相关阅读:
    023_带标签的break和continue
    5.利用for循环打印九九乘法表
    4.用while和for循环输出1到100之间能被5整除的数,且每行输出3个。
    Python字典由value查key
    python保存字典到文件
    python查找列表中某个元素所有下标的两个方法
    聚类算法评估指标:IoU, mPA, MoF
    二分图与匈牙利算法,Python实现
    行为检测和识别领域的一些研究人员的主页及文章代码的链接
    python 计时
  • 原文地址:https://www.cnblogs.com/jianshu/p/5593700.html
Copyright © 2011-2022 走看看