• Hibernate框架之Criteria查询


    首先给大家说说Hibernate检索方式

      Hibernate提供了5种检索对象的方式

         1.导航对象图检索方式:根据已经加载的对象导航到其他对象

         2.OID检索方式:按照对象的OID来检索对象

         3.HQL检索方式:使用面向对象的HQL查询语言

         4.QBC检索方式:使用QBC(Query By Criteria)API来检索对象,这种API封装了基于字符串形式的查询语句,提供了更加面向对象的查询接口

         5.本地SQL检索方式:使用本地数据库的SQL查询语句

    Criteria查询是Hibernate提供的另一种查询方式,与HQL基于字符串的查询形式完全不同。Hibernate提供了org.hibernate.Criteria接口,org.hibernate.criterion.Critereion接口和org.hibernate.criterion.Restrictions类等Criteria API,用于支持在运行时动态生成查询语句。

    一:条件查询

    使用Criteria查询包括以下步骤:

    1.使用Session接口的createCriteria()方法创建Criteria对象

    2.使用Restrictions类提供的静态方法设置查询条件,这些静态方法返回Criterion对象,一个Criterion对象代表一个查询条件。Criteria借口的add()方法用来添加查询条件。

    3.使用Criteria接口的list()方法执行查询语句,list()方法返回java.util.List类型的结果,List集合中的每个元素都是持久化对象。

    实例一:使用Criteria查询所有的部门

    Session session;
        Transaction tx;
        
        //单元测试前走
        @Before
        public void Before(){
            session= HibernateUtil.currentSession();        
             tx= session.beginTransaction();        
        }
    
        //单元测试后走
        @After
        public void After(){
            tx.commit();        
            HibernateUtil.closeSession();    
        }
        
        @SuppressWarnings("unchecked")
        @Test //使用Criteria查询所有的部门名称
        public void TestOne(){                
            Criteria criteria = session.createCriteria(Dept.class);
            List<Dept> list = criteria.list();
            for (Dept dept : list) {
                System.out.println(dept.getDeptname());
            }                            
        }
    View Code

    实例二:查询部门表为"财务部2"的部门  --Restrictions.between()

    public void TestThree(){                    
            List<Dept> list=session.createCriteria(Dept.class).add(Restrictions.eq("deptname", "财务部2")).list();
            for (Dept dept : list) {
                System.out.println(dept.getDeptname());
            }        
        }
    View Code

    实例三:查询部门表的deptname为"财务部2"和"财务部"的名称(链式编程风格)  --Restrictions.in()

    @Test //查询Dept的deptname为财务部2和财务部的名称(链式编程风格)
        public void TestFour(){        
            List jobList=new ArrayList<String>();//定义一个数组
            jobList.add("财务部");
            jobList.add("财务部2");
            List<Dept> list=session.createCriteria(Dept.class).add(Restrictions.in("deptname", jobList)).list();
            for (Dept dept : list) {
                System.out.println(dept.getDeptname());
            }                    
        }
    View Code

    实例四:查询Empinfo表的ehomezipcode(薪资)在500到100000  --Restrictions.between()

        @Test //查询Empinfo的ehomezipcode在500到100000
        public void TestFive(){     
            List<Empinfo> list=session.createCriteria(Empinfo.class).add(Restrictions.between("ehomezipcode", 500, 100000)).list();
            for (Empinfo empinfo : list) {
                System.out.println(empinfo.getEname());
            }            
        }
    View Code

    实例五:查询部门表中名字有"总"子的员工 --like() ilike()

        @Test //查询Empinfo的ename在中有 总 
            public void TestSix(){ 
               //like 字符串模式匹配 
               //ilike 字符串模式匹配 同时忽略大小写
                List<Empinfo> list=session.createCriteria(Empinfo.class).add(Restrictions.like("ename", "%总%")).list();
                for (Empinfo empinfo : list) {
                    System.out.println(empinfo.getEname());
                }                            
            }
    View Code

    MatchMode类的四种模式:

    MatchMode.START:字符串在最前面的位置.相当于"like 'key%'"
    MatchMode.END:字符串在最后面的位置.相当于"like '%key'"
    MatchMode.ANYWHERE:字符串在中间匹配.相当于"like '%key%'"
    MatchMode.EXACT:字符串精确匹配.相当于"like 'key'"

    实例六:查询Empinfo的ename在中"张总"或"王总" --Restrictions.or()

        @Test //查询Empinfo的ename在中张总或王总
            public void TestSeven(){                     
                List<Empinfo> list=session.createCriteria(Empinfo.class).add(Restrictions.or(Restrictions.eq("ename", "张总"), Restrictions.eq("ename", "王总"))).list();
                for (Empinfo empinfo : list) {
                    System.out.println(empinfo.getEname());
                }
            }
    View Code

    实例七:查询没有员工的部门  --Restrictions.isEmpty()

    @Test //查询没有员工的部门
            public void TestEight(){                     
                List<Dept> list=session.createCriteria(Dept.class)
                        .add(Restrictions.isEmpty("emps"))
                        .list();
                for (Dept dept : list) {
                    System.out.println(dept.getDeptname());
                }
            }
    View Code

    二:动态查询   --根据判断用户给的条件查询

    实例一:Empinfo表中查询条件可为:

    1.薪资大于8000

    2.街道是"北京大街"

    3.城市为"北京"

    @Test 
            public void TestNice(){                     
             Criteria criteria = session.createCriteria(Empinfo.class); 
               //00.构建出一个和page对应的条件类,依次判定条件是否为空
               Empinfo empinfo=new Empinfo();
               empinfo.setEhomecity("北京");
               empinfo.setEhomestreet("北京大街");
               empinfo.setEhomezipcode(8000);
               
               //1.2判定之后,动态拼接检索条件
               if (empinfo.getEhomecity()!=null) {
                   //用户填写了城市作为检索条件
                   criteria.add(Restrictions.eq("ehomecity", empinfo.getEhomecity()));
               }
               if(empinfo.getEhomeprovince()!=null){
                   //用户填写薪资作为筛选条件
                   criteria.add(Restrictions.gt("ehomeprovince", empinfo.getEhomeprovince()));
               }
               if (empinfo.getEhomestreet()!=null) {
                   //用户填写街道作为筛选条件
                   criteria.add(Restrictions.eq("ehomestreet", empinfo.getEhomestreet()));
                }
                List<Empinfo> list = criteria.list();
                for (Empinfo emp : list) {
                    System.out.println(emp.getEname());
                }
    
            }
    View Code

    三:排序查询

    HQL使用order by 字句对查询结果排序,Criteria查询使用org.hibernate.criterion.Order类对查询结果排序

    升序:addOrder(Order.asc())

    降序:addOrder(Order.desc())

    实例一:查询Empinfo表按工资升序  --addOrder(Order.asc())

    @Test
        // 查询Empinfo按工资升序
        public void TestOne() {        
            List<Empinfo> list = session.createCriteria(Empinfo.class)
                    .addOrder(Order.asc("ehomezipcode")).list();
            for (Empinfo empinfo : list) {
                System.out.println(empinfo.getEhomezipcode());
            }    
        }
    View Code

    四:分页查询

    Criteria接口提供了设置分页的方法

    setFirstResult(int firstResult):设置从哪一个对象开始查询,参数firstResult是个对象在查询结果中的位置,位置的起始值是0

    setMaxResult(int maxResult):设置一次最多查询出的对象个数

    实例一:分页查询按工资升序后的Empinfo表

        @Test
        // 分页查询Empinfo表
        public void TestTwo() {    
            List<Empinfo> list = session.createCriteria(Empinfo.class)
                    .addOrder(Order.asc("ehomezipcode"))
                    .setFirstResult(0)
                    .setMaxResults(2).list();
            for (Empinfo empinfo : list) {
                System.out.println(empinfo.getEhomezipcode());
            }
        }
    View Code

    五:DetachedCriteria

    DetachedCriteria和Criteria功能类似,它实现了CriteriaSpecification接口
    Criteria是由Session对象创建的
    DetachedCriteria创建时不需要Session对象
    使用DetachedCriteria来构造查询条件
    可以把DetachedCriteria作为方法参数传递给业务层

    实例一:查询财务部的员工

    @SuppressWarnings("unchecked")
        @Test
        public void TestSenven() {    
            DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Emp.class,"e")
                    .createAlias("e.dept", "d")
                    .add(Restrictions.eq("d.deptname", "财务部"));    
            List<Emp> list = detachedCriteria.getExecutableCriteria(session).list();
            for (Emp emp : list) {
                System.out.println(emp.getEmpname());
            }
        
        }
    View Code

    六:查询唯一对象  --uniqueResult()

    uniqueResult()方法用于查询唯一对象。需要注意,必须明确知道查询结果中只有一个对象,才可以直接使用uniqueResult()方法。

    实例一:查询Emp表总记录数

    @Test
        // 查询Emp表总记录数
        public void TestThree2() {    
            Integer result =(Integer) session.createCriteria(Emp.class)
            .setProjection(Projections.count("empno")).uniqueResult();
            System.out.println(result);
        }
    View Code

     七:连接查询

    1.内连接

      01.使用createCriteria()

    实例一:查询财务部的姓名中包括“总”的员工

    @Test
        // 查询财务部的姓名中包括“总”的员工
        public void TestFour() {    
            List<Emp> list = session.createCriteria(Emp.class)
                    .add(Restrictions.ilike("empname", "总", MatchMode.ANYWHERE))
                    .createCriteria("dept")
                    .add(Restrictions.eq("deptname", "财务部").ignoreCase()).list();
            for (Emp emp : list) {
                System.out.println(emp.getEmpname());
            }
        
        }
    View Code

      02.使用createAlias()

    实例一:查询财务部的姓名中包括“总”的员工

    @Test
        // 查询财务部的姓名中包括“总”的员工
        public void TestFive() {
    
        
            List<Emp> list = session.createCriteria(Emp.class, "e")
                    .createAlias("dept", "d")
                    .add(Restrictions.ilike("e.empname", "总", MatchMode.ANYWHERE))
                    .add(Restrictions.eq("d.deptname", "财务部").ignoreCase()).list();
            for (Emp emp : list) {
                System.out.println(emp.getEmpname());
            }
            
        }
    View Code

    2.迫切左连接  --setFetchMode()

    实例一:查询部门为“财务部”的员工个数

    @Test
        // 查询部门为“财务部”的员工个数
        public void TestSix() {
            List<Dept> list = session.createCriteria(Dept.class, "d")
                    .setFetchMode("emps", FetchMode.JOIN)
                    .add(Restrictions.eq("deptname", "财务部"))
                    .list();
            //使用Set接口的实现类HashSet来过滤重复的数据(HashSet中不会存储相同的值)
            HashSet<Dept> set=new HashSet<Dept>(list);
            for (Dept dept : set) {
                System.out.println(dept.getDeptname()+","+dept.getEmps().size());
            }    
        }
    View Code
  • 相关阅读:
    webpack 打包报 ERROR in static/js/vendor.2eff2b5a1d36f4b7f033.js from UglifyJs
    常见重构技巧
    Java常见重构技巧
    Python写基于非线性优化的2D-SLAM系统(已开源)
    分享一个免费开源压缩视频软件!!!【视频压缩后质量还可以】
    AJAX之超时与网络异常处理
    HTTP
    Gin多次读取body
    高效的数据压缩编码方式 Protobuf
    TCP报文之-tcp dup ack 、tcp Out-of-Order
  • 原文地址:https://www.cnblogs.com/zhangzongle/p/5796499.html
Copyright © 2020-2023  润新知