Criteria查询

QBC: Criteria查询

Criteria查询(上)

  • QBC:Query By Criteria 标准查询 JPA中Criteria
    SQL、HQL 或者各种关键字的语句都不需要书写。全部用方法代替。
    Hibernate5.2之前 session.createCriteria(XX);
    Hibernate5.2之后 建造者模式 重点

1.基础查询

//基础查询,查询所有
    @Test
    public  void test01() {
        Session session = HibernateUtils.getCurrentSession();
        Transaction t=  session.beginTransaction();
        try {
            //1.创建CriteriaBuilder对象,用于构建查询条件
            CriteriaBuilder cBuilder= session.getCriteriaBuilder();
            //2.构建Criteria查询对象同时要声明返回的结果类型:Person
            CriteriaQuery<Person> cQuery= cBuilder.createQuery(Person.class);
            //2.1指明要查询哪一个java持久化类  ,可以等价于HQL语句:from com.qf.domain.Person
            cQuery.from(Person.class);
            //3.执行Criteria查询
            List<Person> list = session.createQuery(cQuery).list();
            System.out.println(list);
            t.commit();
        } catch (Exception e) {
            // TODO: handle exception
            if (t!=null) {
                t.rollback();
            }
        }

    }

2.条件查询

1.常用条件

/**
     * where后跟的条件符:
     * >      gt()  大于
     * >=     ge()  大于等于
     * <      lt()  小于
     * <=     le()  小于等于
     * ==     equal()
     * !=     notEqual()
     * 
     * path<Number>:Integer,long,short.....
     * 
     * 
     * between A and B  在A和B之间
     * in (......)    在某个集合范围内
     * like           模糊匹配
     * notlike        不能匹配到的是
     * and        and()  和
     * or        or()   或者
     * 空                isNull
     *          isNotNUll
     */

2.相关名称解释

/**
     * JPA中的:
     * Expression接口: 查询表达式 Type for query expressions.  提供的方法: isNull()  isNotNull()  in(Object... values)
     * 
     * Path和Predicate是Expression的实现类
     * Path:从绑定的类(type)或者集合(collection)中查找简单或者复杂的属性路径。
     * 程序:from(Person.class)  查找指定属性 Path<Integer> path = get("属性名"):
     *    
     * Predicate:  同时发生的多个或者单个限制条件
     * 
     * a conjunction(连接词,同时发生) or   disjunction(分离) of restrictions.    restrictions  限制条件
     */

3.代码示例:

@Test
    public void test02() {
        Session session =  HibernateUtils.getCurrentSession();
        Transaction transaction  =  session.beginTransaction();
        try {   
            //1.创建CriteriaBuilder对象,用来构建查询条件
            CriteriaBuilder cBuilder =session.getCriteriaBuilder();
            //2.构建CriteriaQuery对象,同时指定的是查询的返回的结果类型
            CriteriaQuery<Person> criteriaQuery = cBuilder.createQuery(Person.class);
            //2.1指定查询哪个类
            Root root = criteriaQuery.from(Person.class);       
            //2.2构建查询条件 写where后的条件
            //参数1:字段表达式 ,参数2:要比较的值
            //需求:age大于20岁的
            //从Person类上查找age属性的路径
            //比较大小:gt,ge,lt,le,equal,notEqual
            Path<Integer> age =  root.get("age");
            //Predicate条件: gt(age, 20);  通过指定路径的属性映射的列名和后面的值去比较
            Predicate pAge= cBuilder.equal(age, 18);    
            //条件必须放在where后面
            criteriaQuery.where(pAge);



            //3执行Criteria查询
            Query<Person> query = session.createQuery(criteriaQuery);   
            System.out.println(query.list());
            transaction.commit();
        } catch (Exception e) {
            // TODO: handle exception
            if (transaction!=null) {
                transaction.rollback();
            }
        }

    }


    @Test
    public void test03() {
        Session session =  HibernateUtils.getCurrentSession();
        Transaction transaction  =  session.beginTransaction();
        try {   
            //1.创建CriteriaBuilder对象,用来构建查询条件
            CriteriaBuilder cBuilder =session.getCriteriaBuilder();
            //2.构建CriteriaQuery对象,同时指定的是查询的返回的结果类型
            CriteriaQuery<Person> criteriaQuery = cBuilder.createQuery(Person.class);
            //2.1指定查询哪个类
            Root root = criteriaQuery.from(Person.class);       

            //2.2构建查询条件 写where后的条件
            //参数1:字段表达式 ,参数2:要比较的值
            //需求:name中含有g的Person
            //从Person类上查找name属性的路径
            Path<String> name =  root.get("name");
            Path<Integer> age =  root.get("age");
            //Predicate条件:
            Predicate pAge1= cBuilder.like(name, "%g%");    
            //Predicate pAge= cBuilder.notLike(name, "%g%");    
             Predicate pAge2 =cBuilder.isNotNull(age);
            Predicate p1=  cBuilder.and(pAge1,pAge2);
            //条件必须放在where后面
            criteriaQuery.where(p1);

            //3执行Criteria查询
            Query<Person> query = session.createQuery(criteriaQuery);   
            System.out.println(query.list());
            transaction.commit();
        } catch (Exception e) {
            // TODO: handle exception
            if (transaction!=null) {
                transaction.rollback();
            }
        }

    }

Criteria查询( 下)

1.分页查询:

    @Test
    public void test02() {
        Session session = HibernateUtils.getCurrentSession();
        Transaction transaction=  session.beginTransaction();
        try {
            //1.得到CriteriaBuilder的对象,构建查询条件的
            CriteriaBuilder cBuilder=  session.getCriteriaBuilder();
            //2.得到CriteriaQuery对象,同时指定返回类型
            CriteriaQuery<Person> cQuery= cBuilder.createQuery(Person.class);
            //3.查询指定的类
            Root root = cQuery.from(Person.class);
            //4.执行查询
            Query<Person>  query = session.createQuery(cQuery);
            query.setFirstResult(0);
            query.setMaxResults(2);
            System.out.println(query.list());
            transaction.commit();
        } catch (Exception e) {
            // TODO: handle exception
            if (transaction!=null) {
                transaction.rollback(); 
            }
        }
    }

2.排序查询:

    @Test
    public void test01() {
        Session session = HibernateUtils.getCurrentSession();
        Transaction transaction=  session.beginTransaction();
        try {
            //1.得到CriteriaBuilder的对象,构建查询条件的
            CriteriaBuilder cBuilder=  session.getCriteriaBuilder();
            //2.得到CriteriaQuery对象,同时指定返回类型
            CriteriaQuery<Person> cQuery= cBuilder.createQuery(Person.class);
            //3.查询指定的类
            Root root = cQuery.from(Person.class);
            //3.1加排序 递增asc,递减desc  (属于条件类的)
            Path<String>  path=  root.get("IDCard");    
            //3.2构建排序的条件
            Order order= cBuilder.desc(path);
            //3.3加入查询的条件
            cQuery.orderBy(order);
            //4.执行查询
            Query<Person> query = session.createQuery(cQuery);
            System.out.println(query.list());
            transaction.commit();
        } catch (Exception e) {
            // TODO: handle exception
            if (transaction!=null) {
                transaction.rollback(); 
            }
        }
    }

3.聚合函数查询:


    //在JPA中的Criteria的所有查询中要执行调用的是以前sql中关键字的方法
     //示例: from()  select()  orderby()    where() 
    //但是条件必须都是CriteriaBuilder

    //在JPA中的Criteria的聚合函数查询中:
    //1. sum,max,min的类型跟所查询的列的类型一致
    //3. avg  结果类型是Double类型
    //4. count  结果类型是Long类型
    @Test
    public void test03() {
        Session session = HibernateUtils.getCurrentSession();
        Transaction transaction=  session.beginTransaction();
        try {
            //1.得到CriteriaBuilder的对象,构建查询条件的
            CriteriaBuilder cBuilder=  session.getCriteriaBuilder();
            //2.得到CriteriaQuery对象,同时指定结果返回类型
            CriteriaQuery<Long> cQuery= cBuilder.createQuery(Long.class);
            //3.查询指定的类
            Root root = cQuery.from(Person.class);
            //聚合函数select 后和from前

            //1.需求1:sum(age)
            //1.1先找出age列的路径
            /*Path<Integer> agePath = root.get("age");
            //1.2根据sum构建条件
            Expression<Integer> expression = cBuilder.sum(agePath);
            cQuery.select(expression);*/

             //2.需求2: count(age)
            Path<Long> agePath = root.get("age");
            //1.2根据sum构建条件
            Expression<Long> expression = cBuilder.count(agePath);
            cQuery.select(expression);

            Long sum = session.createQuery(cQuery).uniqueResult();
            System.out.println(sum);
            transaction.commit();
        } catch (Exception e) {
            // TODO: handle exception
            System.out.println(e.getMessage());
            if (transaction!=null) {
                transaction.rollback();

            }
        }
    }

4.查询多个列:

//查询多个列(name,address)
    @Test
    public void test04() {
        Session session = HibernateUtils.getCurrentSession();
        Transaction transaction=  session.beginTransaction();
        try {
            //1.得到CriteriaBuilder的对象,构建查询条件的
            CriteriaBuilder cBuilder=  session.getCriteriaBuilder();
            //2.得到CriteriaQuery对象,同时指定返回类型
            CriteriaQuery<Object[]> cQuery= cBuilder.createQuery(Object[].class);
            //3.查询指定的类
            Root root = cQuery.from(Person.class);
            //3.1 先查找name和address属性所在的Path路径
            Path namePath=  root.get("name");
            Path addressPath=  root.get("address");
            //3.2. 最终目的:select  name,address from  com.qf.domainn.Person
            //方式一:
            //cQuery.multiselect(namePath,addressPath);
            //方式二:
 //cBuilder.array(namePath,addressPath)表示把所有条件放在一个array组成一个新的对象
            cQuery.select(cBuilder.array(namePath,addressPath));

            //4.执行查询
            List<Object[]> list = session.createQuery(cQuery).list();
            for (int i = 0; i < list.size(); i++) {
                Object[] objects = list.get(i);
                System.out.println(objects[0]+"==ffff=="+objects[1]);
            }
            transaction.commit();
        } catch (Exception e) {
            // TODO: handle exception
            if (transaction!=null) {
                transaction.rollback(); 
            }
        }
    }

5.离线查询:

    //离线查询
    @Test
    public void test05() {
        Session session = HibernateUtils.getCurrentSession();
        Transaction transaction=  session.beginTransaction();
        try {
        //1.创建一个DetachedCriteria类,并且指明要查询的持久化类
        DetachedCriteria  detachedCriteria= DetachedCriteria.forClass(Person.class);
        //2.添加查询条件
        //2.1 Restrictions封装了大量的查询条件,例如:gt,ge,lt,eq........
        detachedCriteria.add(Restrictions.gt("age", 18));       
        //执行数据增删查改操作:
        Criteria c = detachedCriteria.getExecutableCriteria(session);
        System.out.println(c.list());
        transaction.commit();
        } catch (Exception e) {
            // TODO: handle exception
            if (transaction!=null) {
                transaction.rollback(); 
            }
        }
    }

6.分层思想中Criteria查询

6.1 在线查询:
/**
 *    在线查询:
 *    完全依赖于Session(包含数据库操作的条件构建以及数据库操作的增删查改)  
 *    分层思想: dao层只做增删查改
 *   web层----------------- service层-------------------dao层
 * 取参数调用service         业务逻辑(事务)            条件构建和增删查改
 *
 *   在线查询:service和web层还是以前的写法不需要任何变化。
 *    dao层书写方式如下:
 *    @Override
      public Person queryPersonById(String  id) {
        // TODO Auto-generated method stub
        Session session = HibernateUtils.getCurrentSession();
        //1.CriteriaBuilder
        CriteriaBuilder  cb = session.getCriteriaBuilder();
        //2.CriteriaQuery
        CriteriaQuery<Person> cQuery =  cb.createQuery(Person.class);    
        //3.指定查询那个类
        Root root = cQuery.from(Person.class);      
        //构建条件
        Path<String> idPath= root.get("IDCard");
        Predicate predicate =cb.equal(idPath, id);
        cQuery.where(predicate);   
        //4.执行查询
        Person person = session.createQuery(cQuery).uniqueResult();
        return person;
    }
6.2.离线查询
离线查询:数据库操作的条件构建不需要依赖于session而创建
 /* 分层思想中:
 *   web层----------------- service层-----------------dao层
 * 取参数调用service         业务逻辑(事务)            增删查改
 * 查询条件的构建都放在web层。
 *
 *  web层关键代码如下:
 public static void main(String[] args) {
        //查询id为xxx的值,示例:IDcard=8a8003c55fe18602015fe18605800000
        //扮演的是web层的Servlet的角色
        //1.获取请求参数
        String id="8a8003c55fe18602015fe18605800000";
        //2.调用service层处理
        PersonService personService =new PersonServiceImpl();
        //构建查询条件
        DetachedCriteria criteria=DetachedCriteria.forClass(Person.class);
        criteria.add(Restrictions.idEq(id));

        Person person = personService.findPersonById(criteria);
        System.out.println(person);
        //3.得到结果
        if (person!=null) {
            System.out.println("查询成功");
        }else {
            System.out.println("查询失败");
        }
    }
 *
 *dao层代码如下: 
 *@Override
    public Person queryPersonById(DetachedCriteria detachedCriteria) {
        // TODO Auto-generated method stub
        //真正的查询
        Session session = HibernateUtils.getCurrentSession();
        //执行封装的条件
        Criteria c = detachedCriteria.getExecutableCriteria(session);   
        //取结果
         Person person =  (Person) c.uniqueResult();
        return person;
    }
 */

补充: 离线查询的聚合函数查询:

@Test
    public void test06() {
        Session session = HibernateUtils.getCurrentSession();
        Transaction transaction=  session.beginTransaction();
        try {
        //1.创建一个DetachedCriteria类,并且指明要查询的持久化类
        DetachedCriteria  detachedCriteria= DetachedCriteria.forClass(Person.class);        
        //执行数据增删查改操作:
        Criteria c = detachedCriteria.getExecutableCriteria(session);
       /* c.setProjection(Projections.max("age"));
        c.setProjection(Projections.min("age"));
        c.setProjection(Projections.sum("age"));
        c.setProjection(Projections.avg("age"));*/
        c.setProjection(Projections.count("IDCard"));
        System.out.println(c.uniqueResult());
        transaction.commit();
        } catch (Exception e) {
            // TODO: handle exception
            if (transaction!=null) {
                transaction.rollback();     
            }
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值