zoukankan      html  css  js  c++  java
  • Hibernate之HQL

    什么是HQL?

    HQL是Hibernate Query Language的缩写,提供更加丰富灵活、更为强大的查询能力;HQL更接近SQL语句查询语法。

    HQL与SQL有何不同:

      1.HQL

    • 对查询条件进行了面向对象封装,符合编程人员的思维方式,格式:from + 类名 + 类对象 + where + 对象的属性

    • 区分大小写,关键字不区分大小写 

    • 从下标0开始计算位置(hibernate5之后不支持)

    • 支持命名参数

      2.SQL

    • sql是面向数据库表查询,格式:from + 表名 + where + 表中字段

    • 不区分大小写

    • 从顺序1开始计算位置

    • 不支持:命名参数

     处理返回的结果集

    • 单个对象

    • 多个列段

    1. object【】
    2. 对象(多个列段、全部)
    • Map

    这里写了一个JUnit测试类来测试这些效果

    注意:测试类中需要设置session,transaction属性,然后就可以在类中写方法论

        1.  单个对象
         select没有逗号

      如果是单个列段的话,就直接可以用String接收对象,这样就避免一些麻烦

    /**
         * 返回单个列段,用字符串就可以接受
         */
        @Test
        public void testList2() {
            Query query = session.createQuery("select b.bookName as ss from Book b");
            List<String> list = query.list();
            for (String b : list) {
                System.out.println(b);
            }
        }

    效果:

      2.1 Object[]

        b.bookId, b.bookName...

      如果有两个或者两个以上的列段可以用数组来接收

    /**
         * 查两个列段及以上,默认返回的是Object【】
         */
        @Test
        public void testList3() {
            Query query = session.createQuery("select b.bookId,b.bookName as ss from Book b");
            List<Object[]> list = query.list();
            for (Object[] b : list) {
                System.out.println(Arrays.toString(b));
            }
        }

    效果:

      2.2 book对象

      其实两个以上也可以用对象来接收

    /**
         * 查两个列段及以上,也可返回对象,前提是有对应的构造函数
         */
        @Test
        public void testList5() {
            Query query = session.createQuery("select new Book(b.bookId,b.bookName) from Book b");
            List<Book> list = query.list();
            for (Book b : list) {
                System.out.println(b);
            }
        }

    效果:

      2.2.1 也是用对象来接收 

    /**
         * 返回对象(多个)
         */
        @Test
        public void testList1() {
            Query query = session.createQuery("from Book");
            List<Book> list = query.list();
            for (Book b : list) {
                System.out.println(b);
            }
        }

      效果:

      

      3.Map

        new Map(b.bookId as bid, b.bookName as bname)

    /**
         * 注意map是函数,所以不区分大小写,返回的是map集合
         */
        @Test
        public void testList4() {
            Query query = session.createQuery("select new mAp(b.bookId,b.bookName) from Book b");
            List<Map> list = query.list();
            for (Map b : list) {
                System.out.println(b);
            }
        }

     效果:

    HQL中使用占位符

    • 占位符从下标0开始计算位置

        hibernate5之后不再支持占位符

    • 命名参数的使用
    /**
         * HQL语句支持占位符
         */
        @Test
        public void testList6() {
    //        Query query = session.createQuery("from Book where bookId = :bookId");
    //        query.setParameter("bookId", 1);
    //        Book b = (Book) query.getSingleResult();
    //        System.out.println(b);
            
            Query query = session.createQuery("from Book where bookId in (:bookIds)");
            query.setParameterList("bookIds", new Integer[] {1,2,4});
    //        List<Integer> params = new ArrayList<Integer>();
    //        params.add(1);
    //        params.add(2);
    //        params.add(4);
    //        query.setParameterList("bookIds", params);
            List<Book> list = query.list();
            for (Book b : list) {
                System.out.println(b);
            }
        }

    命名参数的用法就是:

     Query query = session.createQuery("from Book where bookId in (:bookIds)");
            query.setParameterList("bookIds", new Integer[] {1,2,4});

    连接查询

    /**
         * HQL支持连接查询
         */
        @Test
        public void testList7() {
            Query query = session.createQuery("select o.orderNo,oi.quantity from Order o,OrderItem oi where o = oi.order");
            List<Object[]> list = query.list();
            for (Object[] b : list) {
                System.out.println(Arrays.toString(b));
            }
        }

    聚合函数

    • sum    总计

    • avg    平均值

    • max    最大

    • min    最小

    • count  总数

    /**
         * HQL支持聚合函数
         */
        @Test
        public void testList8() {
            Query query = session.createQuery("select count(*) from Book");
            Long singleResult = (Long) query.getSingleResult();
            System.out.println(singleResult);
        }

    HQL分页

    /**
         * HQL分页
         */
        @Test
        public void testList9() {
            Query query = session.createQuery("from Book");
            query.setFirstResult(2);
            query.setMaxResults(3);
            List<Book> list = query.list();
            for (Book b : list) {
                System.out.println(b);
            }
        }

    使用HQL实现通用查询

    BaseDao类

    这就是通用的实体查询类

    package com.ht.five.Dao;
    import java.util.Collection;
    import java.util.List;
    import java.util.Map;
    import java.util.Map.Entry;
    import java.util.Set;
    import org.hibernate.Query;
    import org.hibernate.Session;
    import com.ht.five.Util.PageBean;
    
    /**
     * 通用查询类
     * @author Administrator
     *
     */
    public class BaseDao {
        /**
         * @param map 将要设置的阐述用Map的形式来传递
         * @param query 查询对象
         */
        public void setParam(Map<String, Object> map, Query query) {
            if(map != null && map.size() > 0) {
                Object value = null;
                Set<Entry<String, Object>> entries = map.entrySet();
                for (Entry<String, Object> entry : entries) {
                    value = entry.getValue();
                    //判断类型,根据类型来设置命名参数的值
                    if(value instanceof Object[]) {
                        query.setParameterList(entry.getKey(), (Object[])value);
                    }else if(value instanceof Collection) {
                        query.setParameterList(entry.getKey(), (Collection)value);
                    }else {
                        query.setParameter(entry.getKey(), value);
                    }
                }
            }
        }
        /**
         * 传入hql语句 ,返回该语句所查到的总行数
         * @param hql
         * @return
         */
        public String getCountHql(String hql) {
            /**
             * 下面这种做法的原因是请看这两条hql语句:
             * from Book 
             * select * from Book
             * 
             * 所有要想使这个方法同意就是将from这个位置做截断拼接
             */
            //获取到FROM的位置
            int index = hql.toUpperCase().indexOf("FROM");
            //直接从FROM截断,将select count(*) 拼接上就ok了
            return "select count(*)" + hql.substring(index);
        }
    
        
        /**
         *通用查询方法
         * @param session
         * @param map
         * @param hql
         * @param pageBean
         * @return
         */
        public List executeQuery(Session session, Map<String, Object> map, String hql, PageBean pageBean) {
            List list = null;
            if(pageBean != null && pageBean.isPagination()) {
                //获取该查询的总行数
                String countHql = getCountHql(hql);
                Query countQuery = session.createQuery(countHql);
                //给预定于的hql语句的命名参数赋值
                this.setParam(map, countQuery);
                //将总行数放入PageBean对象
                pageBean.setTotal(countQuery.getSingleResult().toString());
                
                Query query = session.createQuery(hql);
                //给预定于的hql语句的命名参数赋值
                this.setParam(map, query);
                //设置开始位置(下标从0开始)
                query.setFirstResult(pageBean.getStartIndex());
                //这是偏移量,就是一页展示几条数据
                query.setMaxResults(pageBean.getRows());
                list = query.list();
            }
            else {
                //如果不分页 直接查
                Query query = session.createQuery(hql);
                this.setParam(map, query);
                list = query.list();
            }
            return list;
        }
    }

    BookDao类

    继承BaseDao,可以调用它的查询方法为自己用

    package com.ht.five.Dao;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import org.hibernate.Session;
    import org.hibernate.Transaction;
    import com.ht.five.Util.PageBean;
    import com.ht.five.Util.StringUtils;
    import com.ht.four.entity.Book;
    import com.ht.two.util.SessionFactoryUtils;
    
    /**
     * 书本Dao方法
     * @author Administrator
     *
     */
    public class BookDao extends BaseDao{
        /**
         * 提供查询书籍并分页的方法 该方法基于父类BaseDao实现
         * @param book
         * @param pageBean
         * @return
         */
        public List<Book> list(Book book, PageBean pageBean){
            Session session = SessionFactoryUtils.openSession();
            Transaction transaction = session.beginTransaction();
            
            String bookName = book.getBookName();
            Map<String, Object> map = new HashMap();
            String hql = "from Book where 1=1";
            
            if(StringUtils.isNotBlank(bookName)) {
                hql +=  " and bookName like :bookName";
                map.put("bookName", bookName);
            }
            
            //返回list结果集合
            List<Book> list = super.executeQuery(session, map, hql, pageBean);
            transaction.commit();
            session.close();
            return list;
        }
    }

    最后在JNUIT测试类中测试

    private BookDao bookDao=new BookDao();
    
    
    /**
         * 测试通用查询
         */
        @Test
        public void testList() {
            Book book = new Book();
            PageBean pageBean = new PageBean();
            pageBean.setPage(2);//根据下标位置来做起始位置(下标从0开始)
            pageBean.setRows(3);//设置每页展示3条数据
            //带条件查询(模糊查询)
            //book.setBookName("%楼%"); 
            List<Book> list = this.bookDao.list(book, pageBean);
            for (Book b : list) {
                System.out.println(b);
            }
        }

    今日分享完毕,谢谢观看!

  • 相关阅读:
    Selenium的WebDriver API元素定位中的XPath和CSS
    Python中pytesseract库的使用以及注意事项
    Lua语言15分钟快速入门
    day 31 综合架构实时同步服务
    day 30 综合架构存储服务
    day 29 综合架构备份项目
    day 28 综合架构备份服务
    day 27 综合架构开场介绍
    操作系统磁盘管理
    操作系统定时任务
  • 原文地址:https://www.cnblogs.com/huangting/p/11206003.html
Copyright © 2011-2022 走看看