hibernate之HQL

it2022-05-05  69

目录

简介HqlTest功能演示用HQL实现通用方法调用BaseDao方法来执行自己的方法测试方法

简介

什么是HQL? HQL是Hibernate Query Language的缩写是一种查询语言。hql和sql区别/异同 | HQL | SQL | | 类名/属性 |表名/列名| | 区分大小写,关键字不区分大小写 | 不区分大小写| | 别名 | 别名| | ?,从下标0开始计算位置(hibernate5之后不支持)|?,从顺序1开始计算位置| |:命名参数 |不支持:命名参数| |面向对象的查询语言 | 面向对象的查询语言 |处理返回的结果集 返回对象(多个)查询所有返回单个列段,用字符串就可以接受,返回String类型 只查询书的名称查两个列段及以上,默认返回的是Object【】,查询两个列的数据注意map是函数,所以不区分大小写,返回的是map集合,用函数来查询多个列段。查两个列段及以上,也可返回对象,前提是有对应的构造函数HQL语句支持占位符,用变量名代替(?占位符 从下标0开始计算位置)HQL支持连接查询 (select o.orderNo,oi.quantity from Order o,OrderItem oi where o = oi.order)HQL支持聚合函数(sum avg max min count)HQL分页 同样的可以自动根据方言生成分页语句 setFirstResult:设置起始下标 setMaxResults:设置偏移量

HqlTest功能演示

package com.hibernate.test; import java.util.Arrays; import java.util.List; import java.util.Map; import org.hibernate.Session; import org.hibernate.Transaction; import org.hibernate.query.Query; import org.junit.After; import org.junit.Before; import org.junit.Test; import com.hibernate.enetiy.Book; import com.hibernate.util.SessionFactoryUtils; public class HqlTest { private Session session; private Transaction transaction; @Before public void before() { session = SessionFactoryUtils.openSession(); transaction = session.beginTransaction(); } @After public void after() { transaction.commit(); session.close(); } /** * 返回对象(多个) * 查询所有 */ @Test public void testList1() { Query query = session.createQuery("from Book"); List<Book> list = query.list(); for (Book b : list) { System.out.println(b); } } /** * 返回单个列段,用字符串就可以接受 * 返回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); } } /** * 查两个列段及以上,默认返回的是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)); } } /** * 注意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); } } /** * 查两个列段及以上,也可返回对象,前提是有对应的构造函数 * */ @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); } } /** * HQL语句支持占位符 * 用变量名代替? */ @Test public void testList6() { Query query = session.createQuery("from Book where bookId in (:bookIds)"); query.setParameterList("bookIds", new Integer[] {1,2,4}); List<Book> list = query.list(); for (Book b : list) { System.out.println(b); } } /** * HQL支持连接查询 */ @Test public void testList7() { //select * from t_hibernate_order o,t_hinernate_item oi where o.order_id=oi.oid 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)); } } /** * HQL支持聚合函数 */ @Test public void testList8() { //还支持 sum avg max min Query query = session.createQuery("select count(*) from Book"); //getSingleResult是用来获取单条记录的 Long singleResult = (Long) query.getSingleResult(); System.out.println(singleResult); } /** * HQL分页 * * 同样的可以自动根据方言生成分页语句 * oracle * select * from (select t.*,rownum rn hql t where t.rn >5 ) t1 where */ @Test public void testList9() { Query query = session.createQuery("from Book"); //这是是开始位置 切记是从0开始滴 query.setFirstResult(1); //分页偏移量 就是一页展示几条数据 query.setMaxResults(3); List<Book> list = query.list(); for (Book b : list) { System.out.println(b); } } }

用HQL实现通用方法

BaseDao package com.hibernate.util; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import org.hibernate.Session; import org.hibernate.query.Query; /** * 1、设置参数的问题 * 2、分页代码重的问题 * * @author 林凡 * */ public class BaseDao { /** * 通用的参数设值方法 * @param map 参数键值对集合 * @param query 预定义处理的hql对象 * */ private void setParam(Map<String,Object> map, Query query) { if(map !=null && map.size() >0) { Object value =null; Set<Entry<String, Object>> entrySet =map.entrySet(); for (Entry<String, Object> entry : entrySet) { //例子的西游记,但是有的时候它并不是单纯的字符串,可能是数组比如爱好,也可能是集合 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); } } } } public String getCountHql(String hql) { // * hql ="from Book where bookName like :bookName" // * hql ="select * from new Book(bid,bookName) where bookName like :bookName" //获取到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); //给预定义hql语句执行对象中的参数赋值,有多少赋值多少 this.setParam(map, query); list =query.list(); } return list; } }

调用BaseDao方法来执行自己的方法

BookDao public class BookDao extends BaseDao{ /** * 需求 * 写一个带查询条件的并且能分页方法 * @param book * @param pageBean * @return */ public List<Book> list1(Book book,PageBean pageBean) { Session session = SessionFactoryUtils.openSession(); Transaction transaction = session.beginTransaction(); String bookName =book.getBookName(); String hql ="from Book where 1=1"; if(StringUtils.isNotBlank(bookName)) { hql +="and bookName like : bookName "; } //query相当于前面sql所用prepareStatement Query query = session.createQuery(hql); if(StringUtils.isNotBlank(bookName)) { query.setParameter("bookName", bookName); } //通过写上述代码会发现,同样的if判断写了两次 //下面这个代码每个实体类分页都得写 if(pageBean !=null && pageBean.isPagination()) { query.setFirstResult(pageBean.getStartIndex()); query.setMaxResults(pageBean.getRows()); } List<Book> list =query.list(); transaction.commit(); session.close(); return list; } /** * 提供查询书籍并分页的方法 该方法基于父类BaseDao实现 * @param book * @param pageBean * @return */ public List<Book> list12(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集合就ok了 map.put("bookName", bookName); } //返回list结果集合 List<Book> list =super.executeQuery(session, map, hql, pageBean); transaction.commit(); session.close(); return list; } }

测试方法

BookDaoTest public class BookDaoTest { private BookDao bookDao = new BookDao(); @Test public void testList1() { Book book =new Book(); PageBean pageBean =new PageBean(); // book.setBookName("%楼%"); List<Book> list =this.bookDao.list1(book, pageBean); for (Book b : list) { System.out.println(b); } } @Test public void testList2() { Book book =new Book(); PageBean pageBean =new PageBean(); pageBean.setPage(2);//设置从第三条开始查询(0为启始位置) pageBean.setRows(3);//设置每页展示3条数据 // pageBean.setPagination(false); // book.setBookName("%楼%");(like查询带楼字的书) List<Book> list =this.bookDao.list12(book, pageBean); for (Book b : list) { System.out.println(b); } } }

最新回复(0)