zoukankan      html  css  js  c++  java
  • hibernate--HQL

    hibernate--HQL

    1. 什么是hql

    HQL是Hibernate Query Language的缩写,提供更加丰富灵活、更为强大的查询能力;

    HQL更接近SQL语句查询语法。

    2. hql和sql区别/异同  

                  HQL                                                                                SQL
       类名/属性                                                                              表名/列名
       区分大小写,关键字不区分大小写                                        不区分大小写
       别名                                                                                          别名
       ?,从下标0开始计算位置(hibernate5之后不支持)          ?,从顺序1开始计算位置
       :命名参数                                                                         不支持:命名参数
       面向对象的查询语言                                                       面向结构查询语言

    3. 处理返回的结果集 

      3.1 单个对象
          select没有逗号
      3.2 Object[],一般返回的是两个或多个列段
          b.bookId, b.bookName
      3.3 Map 
          new Map(b.bookId as bid, b.bookName as bname)
      3.4 new 构造方法(attr1,attr2)
          new Book(b.bookId, b.price)
      单个列段

     3.5 测试代码

      1 package com.yuan.five.test;
      2 
      3 import java.util.Arrays;
      4 import java.util.List;
      5 import java.util.Map;
      6 
      7 import org.hibernate.Session;
      8 import org.hibernate.Transaction;
      9 import org.hibernate.query.Query;
     10 import org.junit.After;
     11 import org.junit.Before;
     12 import org.junit.Test;
     13 
     14 import com.yuan.four.entity.Book;
     15 import com.yuan.two.util.SessionFactoryUtils;
     16 
     17 public class HqlTest {
     18     private Session session;
     19     private Transaction transaction;
     20     
     21     @Before
     22     public void before() {
     23         session = SessionFactoryUtils.openSession();
     24         transaction = session.beginTransaction();
     25     }
     26     
     27     @After
     28     public void after() {
     29         transaction.commit();
     30         session.close();
     31     }
     32     
     33     /**
     34      * 返回对象(多个)
     35      */
     36     @Test
     37     public void testList1() {
     38         Query query = session.createQuery("from Book");
     39         List<Book> list = query.list();
     40         for (Book b : list) {
     41             System.out.println(b);
     42         }
     43     }
     44     
     45     /**
     46      * 返回单个列段,用字符串就可以接受
     47      */
     48     @Test
     49     public void testList2() {
     50         Query query = session.createQuery("select b.bookName as ss from Book b");
     51         List<String> list = query.list();
     52         for (String b : list) {
     53             System.out.println(b);
     54         }
     55     }
     56     
     57     /**
     58      * 查两个列段及以上,默认返回的是Object【】
     59      */
     60     @Test
     61     public void testList3() {
     62         Query query = session.createQuery("select b.bookId,b.bookName as ss from Book b");
     63         List<Object[]> list = query.list();
     64         for (Object[] b : list) {
     65             System.out.println(Arrays.toString(b));
     66         }
     67     }
     68     
     69     /**
     70      * 注意map是函数,所以不区分大小写,返回的是map集合
     71      */
     72     @Test
     73     public void testList4() {
     74         Query query = session.createQuery("select new mAp(b.bookId,b.bookName) from Book b");
     75         List<Map> list = query.list();
     76         for (Map b : list) {
     77             System.out.println(b);
     78         }
     79     }
     80     
     81     /**
     82      * 查两个列段及以上,也可返回对象,前提是有对应的构造函数
     83      */
     84     @Test
     85     public void testList5() {
     86         Query query = session.createQuery("select new Book(b.bookId,b.bookName) from Book b");
     87         List<Book> list = query.list();
     88         for (Book b : list) {
     89             System.out.println(b);
     90         }
     91     }
     92     
     93     /**
     94      * HQL语句支持占位符
     95      * 
     96      * query对象相当于perparestatement
     97      */
     98     @Test
     99     public void testList6() {
    100 //        Query query = session.createQuery("from Book where bookId = :bookId");
    101 //        query.setParameter("bookId", 1);
    102 //        Book b = (Book) query.getSingleResult();
    103 //        System.out.println(b);
    104         
    105         Query query = session.createQuery("from Book where bookId in (:bookIds)");
    106         query.setParameterList("bookIds", new Integer[] {1,2,4});
    107 //        List<Integer> params = new ArrayList<Integer>();
    108 //        params.add(1);
    109 //        params.add(2);
    110 //        params.add(4);
    111 //        query.setParameterList("bookIds", params);
    112         List<Book> list = query.list();
    113         for (Book b : list) {
    114             System.out.println(b);
    115         }
    116     }
    117     
    118     /**
    119      * HQL支持连接查询
    120      */
    121     @Test
    122     public void testList7() {
    123         Query query = session.createQuery("select o.orderNo,oi.quantity from Order o,OrderItem oi where o = oi.order");
    124         List<Object[]> list = query.list();
    125         for (Object[] b : list) {
    126             System.out.println(Arrays.toString(b));
    127         }
    128     }
    129     
    130     /**
    131      * HQL支持聚合函数
    132      * 如:
    133      * count、sum、avg
    134      */
    135     @Test
    136     public void testList8() {
    137         Query query = session.createQuery("select count(*) from Book");
    138         //getSingleResult:查询返回单行单列的数据
    139         Long singleResult = (Long) query.getSingleResult();
    140         System.out.println(singleResult);
    141     }
    142     
    143     /**
    144      * sql=select * from t_hibernate_book
    145      * sql+limit start,offset
    146      * 1             1,2
    147      * 2            10,10
    148      * 3            20,10
    149      * 
    150      * FirstResult:代表起始下标 start
    151      * MaxResults:代表页大小 offset
    152      * HQL分页
    153      */
    154     @Test
    155     public void testList9() {
    156         Query query = session.createQuery("from Book");
    157         query.setFirstResult(2);
    158         query.setMaxResults(3);
    159         List<Book> list = query.list();
    160         for (Book b : list) {
    161             System.out.println(b);
    162         }
    163     }
    164 }

    4. hql的分页查询

      4.1 PageBean

    package com.yuan.four.util;
    
    import java.util.Map;
    
    import javax.servlet.http.HttpServletRequest;
    
    /**
     * 分页工具类
     *
     */
    public class PageBean {
    
        private int page = 1;// 页码
    
        private int rows = 3;// 页大小
    
        private int total = 0;// 总记录数
    
        private boolean pagination = true;// 是否分页
        // 获取前台向后台提交的所有参数
        private Map<String, String[]> parameterMap;
        // 获取上一次访问后台的url
        private String url;
    
        /**
         * 初始化pagebean
         * 
         * @param req
         */
        public void setRequest(HttpServletRequest req) {
            this.setPage(req.getParameter("page"));
            this.setRows(req.getParameter("rows"));
            // 只有jsp页面上填写pagination=false才是不分页
            this.setPagination(!"fasle".equals(req.getParameter("pagination")));
            this.setParameterMap(req.getParameterMap());
            this.setUrl(req.getRequestURL().toString());
        }
    
        public int getMaxPage() {
            return this.total % this.rows == 0 ? this.total / this.rows : this.total / this.rows + 1;
        }
    
        public int nextPage() {
            return this.page < this.getMaxPage() ? this.page + 1 : this.getMaxPage();
        }
    
        public int previousPage() {
            return this.page > 1 ? this.page - 1 : 1;
        }
    
        public PageBean() {
            super();
        }
    
        public int getPage() {
            return page;
        }
    
        public void setPage(int page) {
            this.page = page;
        }
    
        public void setPage(String page) {
            this.page = StringUtils.isBlank(page) ? this.page : Integer.valueOf(page);
        }
    
        public int getRows() {
            return rows;
        }
    
        public void setRows(int rows) {
            this.rows = rows;
        }
    
        public void setRows(String rows) {
            this.rows = StringUtils.isBlank(rows) ? this.rows : Integer.valueOf(rows);
        }
    
        public int getTotal() {
            return total;
        }
    
        public void setTotal(int total) {
            this.total = total;
        }
    
        public void setTotal(String total) {
            this.total = Integer.parseInt(total);
        }
    
        public boolean isPagination() {
            return pagination;
        }
    
        public void setPagination(boolean pagination) {
            this.pagination = pagination;
        }
    
        public Map<String, String[]> getParameterMap() {
            return parameterMap;
        }
    
        public void setParameterMap(Map<String, String[]> parameterMap) {
            this.parameterMap = parameterMap;
        }
    
        public String getUrl() {
            return url;
        }
    
        public void setUrl(String url) {
            this.url = url;
        }
    
        /**
         * 获得起始记录的下标
         * 
         * @return
         */
        public int getStartIndex() {
            return (this.page - 1) * this.rows;
        }
    
        @Override
        public String toString() {
            return "PageBean [page=" + page + ", rows=" + rows + ", total=" + total + ", pagination=" + pagination
                    + ", parameterMap=" + parameterMap + ", url=" + url + "]";
        }
    
    }

     4.2  StringUtils

     1 package com.yuan.five.util;
     2 
     3 public class StringUtils {
     4     // 私有的构造方法,保护此类不能在外部实例化
     5     private StringUtils() {
     6     }
     7 
     8     /**
     9      * 如果字符串等于null或去空格后等于"",则返回true,否则返回false
    10      * 
    11      * @param s
    12      * @return
    13      */
    14     public static boolean isBlank(String s) {
    15         boolean b = false;
    16         if (null == s || s.trim().equals("")) {
    17             b = true;
    18         }
    19         return b;
    20     }
    21     
    22     /**
    23      * 如果字符串不等于null或去空格后不等于"",则返回true,否则返回false
    24      * 
    25      * @param s
    26      * @return
    27      */
    28     public static boolean isNotBlank(String s) {
    29         return !isBlank(s);
    30     }
    31 
    32 }

      4.3 BookDao

      1 package com.yuan.four.dao;
      2 
      3 
      4 import java.util.HashMap;
      5 import java.util.List;
      6 import java.util.Map;
      7 
      8 import org.hibernate.Hibernate;
      9 import org.hibernate.Session;
     10 import org.hibernate.Transaction;
     11 import org.hibernate.query.Query;
     12 
     13 import com.yuan.five.util.BaseDao;
     14 import com.yuan.four.entity.Book;
     15 import com.yuan.four.entity.Category;
     16 import com.yuan.four.util.PageBean;
     17 import com.yuan.four.util.StringUtils;
     18 import com.yuan.two.util.SessionFactoryUtils;
     19 
     20 
     21 public class BookDao extends BaseDao {
     22     public Integer addBook(Book book) {
     23         Session session = SessionFactoryUtils.openSession();
     24         Transaction transaction = session.beginTransaction();
     25         Integer bid = (Integer) session.save(book);
     26         transaction.commit();
     27         session.close();
     28         return bid;
     29     }
     30     
     31     public Integer addCategory(Category category) {
     32         Session session = SessionFactoryUtils.openSession();
     33         Transaction transaction = session.beginTransaction();
     34         Integer cid = (Integer) session.save(category);
     35         transaction.commit();
     36         session.close();
     37         return cid;
     38     }
     39     
     40     public Category getCategory(Category category) {
     41         Session session = SessionFactoryUtils.openSession();
     42         Transaction transaction = session.beginTransaction();
     43         Category c = session.get(Category.class, category.getCategoryId());
     44         transaction.commit();
     45         session.close();
     46         return c;
     47     }
     48     
     49     public Book getBook(Book book) {
     50         Session session = SessionFactoryUtils.openSession();
     51         Transaction transaction = session.beginTransaction();
     52         Book b = session.get(Book.class, book.getBookId());
     53         if (b != null && new Integer(1).equals(book.getInitCategories())) {
     54             Hibernate.initialize(b.getCategories());
     55         }
     56         transaction.commit();
     57         session.close();
     58         return b;
     59     }
     60     
     61     public void delBook(Book book) {
     62         Session session = SessionFactoryUtils.openSession();
     63         Transaction transaction = session.beginTransaction();
     64         session.delete(book);
     65         transaction.commit();
     66         session.close();
     67     }
     68     
     69     public void delCategory(Category category) {
     70         Session session = SessionFactoryUtils.openSession();
     71         Transaction transaction = session.beginTransaction();
     72         Category c = session.get(Category.class, category.getCategoryId());
     73         if(c!=null) {
     74             for (Book b : c.getBooks()) {
     75 //                通过在被控方通过主控方来解除关联关系,最后被控方再做删除
     76                 b.getCategories().remove(c);
     77             }
     78         }
     79         session.delete(c);
     80         transaction.commit();
     81         session.close();
     82     }
     83     /*******************通用查询********************
     84      */
     85     public List<Book> list1(Book book, PageBean pageBean){
     86         Session session = SessionFactoryUtils.openSession();
     87         Transaction transaction = session.beginTransaction();
     88         //下面代码处理的是bookName实体类的条件查询
     89         String bookName = book.getBookName();
     90         //sql语句where后面可以直接写true,而hql语句不能出现true,
     91         String hql = "from Book where 1=1 ";
     92         if(StringUtils.isNotBlank(bookName)) {
     93             hql += " and bookName like :bookName";
     94         }
     95         Query query = session.createQuery(hql);
     96         if(StringUtils.isNotBlank(bookName)) {
     97             query.setParameter("bookName", bookName);
     98         }
     99         //处理分页
    100         if(pageBean != null && pageBean.isPagination()) {
    101             query.setFirstResult(pageBean.getStartIndex());
    102             query.setMaxResults(pageBean.getRows());
    103         }
    104         
    105         List list = query.list();
    106         
    107         
    108         transaction.commit();
    109         session.close();
    110         return list;
    111     }
    112     
    113     
    114     public List<Book> list2(Book book, PageBean pageBean){
    115         Session session = SessionFactoryUtils.openSession();
    116         Transaction transaction = session.beginTransaction();
    117         
    118         //下面代码处理的是bookName实体类的条件查询
    119         String bookName = book.getBookName();
    120         Map<String, Object> map = new HashMap<String, Object>();
    121         //sql语句where后面可以直接写true,而hql语句不能出现true,
    122         String hql = "from Book where 1=1 ";
    123         if(StringUtils.isNotBlank(bookName)) {
    124             hql += " and bookName like :bookName";
    125             map.put("bookName", bookName);
    126         }
    127         List list =super.executeQuery(session, hql, map, pageBean);
    128         transaction.commit();
    129         session.close();
    130         return list;
    131     }
    132     
    133     
    134     
    135 }

     4.4 最后是本篇的重点 BaseDao

      1 package com.yuan.five.util;
      2 
      3 import java.util.ArrayList;
      4 import java.util.Collection;
      5 import java.util.List;
      6 import java.util.Map;
      7 import java.util.Map.Entry;
      8 import java.util.Set;
      9 
     10 import org.hibernate.Session;
     11 import org.hibernate.query.Query;
     12 
     13 import com.yuan.four.util.PageBean;
     14 
     15 /**
     16  * hibernate的通用查询dao层
     17  * 
     18  * 思想完全借鉴于sql的BaseDao
     19  *   sql = select * from t_mvc_book where bname like '%圣墟%'
     20  *   countSql = select count(1) from (sql)t;
     21  *   pageSql = sql limit start,offset
     22  *   
     23  * hql:
     24  *    hql = select * from Book where bookName like :bookName
     25  *    hql = from Book where bookName like :bookName
     26  * 将原生的hql语句以from关键字进行截取
     27  *    countHql = select count(*) from Book where bookName like :bookName
     28  *    pageHql不需要写,hibernate已经封装了内置的分页接口
     29  *          getFirstResult
     30  *          getMaxResult
     31  * @author ly
    32 * 33 */ 34 public class BaseDao { 35 36 /** 37 * 给hibernate中Query对象中的命名参数列表赋值 38 * @param query 39 * @param map 40 */ 41 public void setParam(Query query,Map<String, Object> map) { 42 if(map !=null && map.size()>0) { 43 Set<Entry<String, Object>> entrySet = map.entrySet(); 44 for (Entry<String, Object> entry : entrySet) { 45 Object value = entry.getValue(); 46 if(value instanceof Collection) 47 query.setParameterList(entry.getKey(), (Collection)value); 48 else if(value instanceof Object[]) 49 query.setParameterList(entry.getKey(), (Collection)value); 50 else 51 query.setParameter(entry.getKey(), value); 52 } 53 } 54 } 55 56 /** 57 * hql = select * from Book where bookName like :bookName 58 * hql = from Book where bookName like :bookName 59 * 将原生的hql语句以from关键字进行截取 60 * countHql = select count(*) from Book where bookName like :bookName 61 * @param hql 62 * @return 63 */ 64 public String getCountHql(String hql) { 65 return "select count(*) " + hql.substring(hql.toUpperCase().indexOf("FROM")); 66 } 67 68 /** 69 * 通用hql语句查询 70 * @param session 当前会话 71 * @param hql 带命名参数的hql语句 72 * @param map 命名参数对应的值的集合 73 * @param pageBean 分页实体类 74 * @return 75 */ 76 public List executeQuery(Session session,String hql,Map<String, Object> map,PageBean pageBean ) { 77 List list = null; 78 Query query = null; 79 if(pageBean != null && pageBean.isPagination()) { 80 String countHql = getCountHql(hql); 81 Query countQuery = session.createQuery(countHql); 82 this.setParam(countQuery, map); 83 pageBean.setTotal(countQuery.getSingleResult().toString()); 84 85 query = session.createQuery(hql); 86 this.setParam(query, map); 87 query.setFirstResult(pageBean.getStartIndex()); 88 query.setMaxResults(pageBean.getRows()); 89 list = query.list(); 90 }else { 91 query = session.createQuery(hql); 92 this.setParam(query, map); 93 list = query.list(); 94 } 95 return null; 96 } 97 98 99 100 }

    4.6 测试类

     1 package com.yuan.four.dao;
     2 
     3 import java.util.List;
     4 
     5 import org.junit.Test;
     6 
     7 import com.yuan.five.util.BaseDao;
     8 import com.yuan.four.entity.Book;
     9 import com.yuan.four.entity.Category;
    10 import com.yuan.four.util.PageBean;
    11 
    12 
    13 public class BookDaoTest {
    14     private BookDao bookDao = new BookDao();
    15 
    16     @Test
    17     public void testGetBook() {
    18         Book book = new Book();
    19         book.setBookId(8);
    20         book.setInitCategories(1);
    21         Book b = this.bookDao.getBook(book );
    22         System.out.println(b.getBookName());
    23         System.out.println(b.getCategories());
    24     }
    25     
    26     /**
    27      * book.hbm.xml    inverse=false
    28      * category.hbm.xml inverse=true
    29      * 数据添加正常
    30      * 书籍表、桥接表各新增一条数据
    31      */
    32     @Test
    33     public void test1() {
    34         Book book = new Book();
    35         book.setBookName("yuan");
    36         book.setPrice(10f);
    37         Category category = new Category();
    38         category.setCategoryId(5);
    39 //        直接将category对象加入到新建的book中是错误的,因为此时的category是临时态的,hibernate是不会管理的
    40 //        book.getCategories().add(category);
    41         Category c = this.bookDao.getCategory(category);
    42         
    43 //        c.getBooks().add(book);
    44         book.getCategories().add(c);
    45         this.bookDao.addBook(book);
    46     }
    47 
    48     /**
    49      * book.hbm.xml    inverse=true
    50      * category.hbm.xml inverse=true
    51      * 只增加书籍表数据
    52      * 桥接表不加数据
    53      * 原因:双方都没有去维护关系
    54      */
    55     @Test
    56     public void test2() {
    57         Book book = new Book();
    58         book.setBookName("yuan2");
    59         book.setPrice(10f);
    60         Category category = new Category();
    61         category.setCategoryId(5);
    62         Category c = this.bookDao.getCategory(category);
    63         
    64         book.getCategories().add(c);
    65         this.bookDao.addBook(book);
    66 //        c.getBooks().add(book);
    67     }
    68     
    69     @Test
    70     public void testList1() {
    71         Book book = new Book();
    72         //查询
    73 //        book.setBookName("%yuan%");
    74         PageBean pageBean = new PageBean();
    75         //分页的第几页
    76         pageBean.setPage(2);
    77         List<Book> list1 = this.bookDao.list1(book, pageBean);
    78         for (Book b : list1) {
    79             System.out.println(b);
    80         }
    81     }
    82     
    83     
    84     @Test
    85     public void testList2() {
    86         Book book = new Book();
    87 //        book.setBookName("%yuan%");
    88         PageBean pageBean = new PageBean();
    89         pageBean.setPage(2);
    90         List<Book> list1 = this.bookDao.list1(book, pageBean);
    91         for (Book b : list1) {
    92             System.out.println(b);
    93         }
    94     }
    95     
    96     
    97 }

     testList1跟testList2的区别是testList1测试的时候BookDao不需要继承BaseDao

     而testList2测试则是依据BaseDao来实现的查询分页,BookDao需要继承BaseDao,所以我们两个方法运行的结果是一样的

    谢谢观看!!!

  • 相关阅读:
    Network (poj1144)
    C. Hongcow Builds A Nation
    ZYB loves Xor I(hud5269)
    D. Chloe and pleasant prizes
    Game(hdu5218)
    约瑟夫环的递推方法
    Misaki's Kiss again(hdu5175)
    Exploration(hdu5222)
    B. Arpa's weak amphitheater and Mehrdad's valuable Hoses
    C. Arpa's loud Owf and Mehrdad's evil plan
  • 原文地址:https://www.cnblogs.com/ly-0919/p/11325794.html
Copyright © 2011-2022 走看看