Hibernate5.2之HQL查詢
一. 介紹
Hibernate的檢索方式分為4種:HQL查詢、原生SQL查詢、OID查詢、QBC查詢。本博客將會出系列教程分別來介紹這四種查詢方式,那么第一篇文章說什么了,筆者認為當然是HQL的查詢。那么是什么是HQL的查詢了,HQL的全稱是Hibernate Query Language, 是面向對象的查詢語言,他和SQL語言有些類似,在Hibernate所提供的各種檢索方式中,HQL是使用上最廣泛的。按照筆者一貫的風格,直接上代碼,本文所用的數據庫為Mysql數據庫。
二. 數據庫的創建
創建orders和customer兩張表(即訂單、客戶表,一個客戶可以有多個訂單),customer和orders是一對多的關系,建表語句如下:
create table customer( id int(11) primary key auto_increment, name varchar(20), phone_number varchar(20) ); create table orders( id int(11) primary key auto_increment, order_id varchar(20), create_time datetime, customer_id int(11) );
數據庫中已有數據以下兩張圖所示:
customer表

orders表

三. POJO類的創建
public class Customer { private int id; private String name; private String phoneNum; private Set<Order> orderSet; //setter and getter } public class Order { private int id; private String orderId; private Date createTime; private Customer customer; public Order() {} public Order(int id, String orderId, Date createTime) { this.id = id; this.orderId = orderId; this.createTime = createTime; } //setter and getter }
四. hbm文件配置
Customer.hbm.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="com.demo.hibernate.one2many.Customer" table="customer"> <id name="id" type="int"> <generator class="increment"></generator> </id> <property name="name" type="string" column="name"></property> <property name="phoneNum" type="string" column="phone_number"></property> <!-- inverse=true表示由對方去維護關聯關系 --> <set name="orderSet" inverse="true"> <key column="customer_id"></key> <one-to-many class="com.demo.hibernate.one2many.Order"/> </set> </class> </hibernate-mapping>
Order.hbm.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="com.demo.hibernate.one2many.Order" table="orders"> <id name="id" type="int"> <generator class="increment"></generator> </id> <property name="orderId" column="order_id" type="string"></property> <property name="createTime" column="create_time" type="timestamp"></property> <many-to-one name="customer" class="com.demo.hibernate.one2many.Customer" column="customer_id"></many-to-one> </class> </hibernate-mapping>
五. 編寫單元測試
在編寫單元測試之讀者需要在hibernate.cfg.xml文件中加入以上兩個hbm文件,在此筆者沒有給出相應的配置,讀者可查詢相關資料自行完成配置。如果有問題,請給筆者留言。
5.1 創建工具類
public class SessionUtils { //獲取SessionFactory public static SessionFactory getSessionFactory(){ StandardServiceRegistry registry = null; SessionFactory sessionFactory = null; try{ registry = new StandardServiceRegistryBuilder().configure("hibernate.cfg.xml").build(); //不指定文件名默認是找hibernate.cfg.xml文件 //registry = new StandardServiceRegistryBuilder().configure().build(); sessionFactory = new MetadataSources(registry).buildMetadata().buildSessionFactory(); }catch(Exception ex){ ex.printStackTrace(); StandardServiceRegistryBuilder.destroy(registry); } return sessionFactory; } //打開並返回一個Session public static Session openSession(){ return getSessionFactory().openSession(); } //關閉Session public static void closeSession(Session session){ if(null != session){ session.close(); } } }
5.2 編寫測試用例
有關於HQL的查詢都會在以下的單元測試類中完成:
public class HibernateTest { private Session session; @Before public void openSession(){ session = SessionUtils.openSession(); //打開會話 } @After public void closeSession(){ SessionUtils.closeSession(session); } }
A.獲取所有的Order對象,得到一個List集合
@Test public void list(){ String hql = "from Order"; Query<Order> query = session.createQuery(hql, Order.class); List<Order> list = query.getResultList(); for(Order o : list){ System.out.println(o.getOrderId() + "::" + o.getCreateTime()); } }
B.獲取Order的分頁數據,得到一個List集合
@Test public void pageList(){ String hql = "from Order"; Query<Order> query = session.createQuery(hql, Order.class); /** * setFirstResult() 是設置從第幾條開始 * setMaxResults() 是設置每頁多少條數據 */ query.setFirstResult(0).setMaxResults(4); List<Order> list = query.getResultList(); for(Order o : list){ System.out.println(o.getOrderId() + "::" + o.getCreateTime()); } }
C.多條件查詢,返回List集合(第一種形式:索引占位符)
@Test public void multiCretiera(){ String hql = "from Order where orderId like ? and createTime between ? and ?"; Query<Order> query = session.createQuery(hql, Order.class); String beginDateStr = "2016-07-26 00:00:00"; String endDateStr = "2016-07-26 23:59:59"; SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); Date beginDate = null; Date endDate = null; try { beginDate = sdf.parse(beginDateStr); endDate = sdf.parse(endDateStr); } catch (ParseException e) { e.printStackTrace(); } query.setParameter(0, "%D%").setParameter(1, beginDate).setParameter(2, endDate); List<Order> list = query.getResultList(); for(Order o : list){ System.out.println(o.getOrderId() + "::" + o.getCreateTime()); } }
E.多條件查詢,返回List集合(第二種形式:命名占位符)
@Test public void multiCretiera1(){ String hql = "from Order where orderId like :orderId and createTime between :beginDate and :endDate"; Query<Order> query = session.createQuery(hql, Order.class); String beginDateStr = "2016-07-26 00:00:00"; String endDateStr = "2016-07-26 23:59:59"; SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); Date beginDate = null; Date endDate = null; try { beginDate = sdf.parse(beginDateStr); endDate = sdf.parse(endDateStr); } catch (ParseException e) { e.printStackTrace(); } query.setParameter("orderId", "%D%").setParameter("beginDate", beginDate).setParameter("endDate", endDate); List<Order> list = query.getResultList(); for(Order o : list){ System.out.println(o.getId() + "::" + o.getOrderId()); }
}
F.大於條件的查詢,使用索引占位符
@Test public void gt(){ String hql = "from Order where id > ?"; Query<Order> query = session.createQuery(hql, Order.class).setParameter(0, 3); List<Order> list = query.getResultList(); for(Order o : list){ System.out.println(o.getId() + "::" + o.getOrderId()); } }
G.更新操作
@Test public void update(){ String hql = "update Order set createTime = ? where id = ?"; Transaction tx = session.beginTransaction(); Query<?> query = session.createQuery(hql).setParameter(0, new Date()).setParameter(1, 1); int i = query.executeUpdate(); System.out.println(i); tx.commit(); session.close(); }
H.刪除操作
@Test public void delete(){ //in 后面的括號可加可不加 String hql = "delete from Order where id in (:idList)"; Transaction tx = session.beginTransaction(); List<Integer> list = new ArrayList<Integer>(); list.add(1); list.add(2); Query<?> query = session.createQuery(hql).setParameter("idList", list); int i = query.executeUpdate(); System.out.println(i); tx.commit(); session.close(); }
I.獲取某一列的值
@Test public void singleValue(){ String hql = "select orderId from Order"; Query<String> query = session.createQuery(hql, String.class); List<String> list = query.getResultList(); for(String o : list){ System.out.println(o); } }
J.使用對象的方式封裝結果數據
@Test public void getOrdersList(){ String hql = "select new com.demo.hibernate.one2many.Order(o.id, o.orderId, o.createTime) from Order as o"; Query<Order> query = session.createQuery(hql, Order.class); List<Order> list = query.getResultList(); for(Order o : list){ System.out.println(o.getId() + ";;" + o.getOrderId() + ";;"); } }
K.獲取關聯對象的結果集
@Test public void getCustomer(){ String hql = "select o.customer from Order o where o.customer.id = 6"; Query<Customer> query = session.createQuery(hql, Customer.class); List<Customer> list = query.getResultList(); for(Customer o : list){ System.out.println(o.getId() + ";;"); } }
L.多列數據的查詢
@Test public void getObjectArray(){ //String hql = "select o.orderId, o.createTime from Order o"; //String hql = "select o.customer.name, o.customer.phoneNum, o.orderId, o.createTime from Order o"; //String hql = "select o.orderId, o.createTime from Order o join o.customer c"; String hql = "select c.name, c.phoneNum, o.orderId, o.createTime from Order o join o.customer c"; Query<Object[]> query = session.createQuery(hql, Object[].class); List<Object[]> list = query.getResultList(); for(Object[] o : list){ System.out.println(o[0] + ";;" + o[1] + ";;"); }
}
M.函數查詢
@Test public void functionQuery(){ String hql = "select max(id), count(*) from Order"; Query<Object[]> query = session.createQuery(hql, Object[].class); Object[] obj = query.getSingleResult(); System.out.println(obj[0] + "::" + obj[1] + "::"); }
N.排序
@Test public void descQuery(){ String hql = "from Order order by id desc"; Query<Order> query = session.createQuery(hql, Order.class); List<Order> list = query.getResultList(); for(Order o : list){ System.out.println(o.getId() + "::" + o.getOrderId()); } }
O.右連接
@Test public void rightJoin(){ String hql = "select o.customer from Order o right join o.customer"; Query<Customer> query = session.createQuery(hql, Customer.class); List<Customer> list = query.getResultList(); for(Customer c : list){ System.out.println(c.getId()); } }
