Hibernate 框架(二)—— SQL 查詢、HQL 查詢

一、SQL 查詢

1、SQL 查詢概述

(1)SQLQuery 是 Hibernate 提供的SQL查詢對象(5.2以前)
(2)NativeQuery 是 Hibernate 提供的SQL查詢對象,通過 sql 語句執行查詢,可查詢一個集合或者一個對象。(5.2以後)

2、SQL 查詢應用

(1)創建 NativeQuery 對象

第一種
NativeQuery query=session.createNativeQuery(sql,Class c);

第一個參數 sql:表示本次查詢執行的sql語句。
第二個參數 Class:表示本次執行查詢結果封裝的實體類對象。

第二種
NativeQuery query=session.createNativeQuery(sql);
query.addEntity(Class c);

參數 sql:表示本次執行查詢的 sql 語句。
addEntity :指定本次查詢結果封裝的實體類對象。

Demo:

Session session = sessionFactory.openSession();
//使用第一種
NativeQuery<Products> query = session.createNativeQuery("select * from products", Products.class);
//使用第二種
NativeQuery<Products> query1 = session.createNativeQuery("select * from products");
query.addEntity(Products.class);
List<Products> list = query.list();
for(Products p: list) {
	System.out.println(p);
}
session.close();

(2)SQL 語句中的動態參數處理
SQL語句可以採用?或者:參數名稱的方式來爲動態參數佔位,例如:

String sql = "select * from student where name like ? and age > ?";
  • 使用?作爲佔位符以後可以使用query.setParameter(序號,值);的方式來爲佔位符賦值,佔位符從1開始。(推薦)
  • 使用?作爲佔位符以後可以使用query.setXxx(序號,值);的方式來爲佔位符賦值,佔位符從1開始。
  • 使用:參數名稱作爲佔位符以後可以使用query.setXxx(“參數名稱”,值);的方式來爲佔位符賦值
  • 使用:參數名稱作爲佔位符以後還可以使用query.setProperties(Map map);的方式來爲所有命名參數同時賦值,需要保證鍵值對和命名參數名稱一致。(推薦)

Demo

Session session = sessionFactory.openSession();
NativeQuery<Products> query = session.createNativeQuery("select * from products where p_price < ? and p_count < ?", Products.class);
query.setParameter(1, 2000);
query.setParameter(2, 1000);
List<Products> list = query.list();
for(Products p: list) {
	System.out.println(p);
}

(3)分頁查詢
如果要分頁查詢,需要在執行查詢前需要先執行兩個方法:

query.setFirstResult(); 設置查詢起始位置
query.setMaxResult(); 設置查詢總行數

Demo

Session session = sessionFactory.openSession();
//分頁查詢
NativeQuery<Products> query = session.createNativeQuery("select * from products", Products.class);
//設置起始位置從0開始
query.setFirstResult(0);
//設置每頁顯示條數
query.setMaxResults(10);
List<Products> list = query.list();
for(Products p: list) {
	System.out.println(p);
}

查詢數據並將查詢出的結果封裝爲集合:query.getResultList();
查詢數據並將查詢出的數據封裝爲一個實體類對象:query.uniqueResult();

Demo:多表聯合查詢

Session session = sessionFactory.openSession();
NativeQuery<Object[]> query = session.createNativeQuery("select p.*,l.lt_pid from products as p inner join ltype as l on p.p_typeid = l.lt_id;");
List<Object[]> list = query.list();
for(Object[] row: list) {
	for(Object p: row) {
		System.out.print(p);
	}
	System.out.println("");
}

在這裏插入圖片描述

二、HQL 查詢

1、HQL 查詢概述

(1)HQL 全稱 Hibernate Query Language,是 Hibernate 設計的面向對象的查詢語言,使用HQL查詢數據時與數據庫的種類和版本無關,Hibernate 最終會根據方言將 HQL 轉爲SQL去數據庫中執行查詢。同時HQL語法和SQL非常類似,非常易於學習和使用,是 Hibernate 推薦的查詢方式之一。
(2)HQL 查詢語句中只能出現類名和屬性名(類名區分大小寫),不能出現表名和字段名,不能出現*號,HQL 中查詢語句中出現的類名必須是進行了對象關係映射的類,沒有映射的類不能出現在HQL語句中。
(3)HQL 查詢語句中如果要使用別名必須使用as關鍵字,不能省略。

2、HQL 語法結構

(1)語法結構

select 
屬性列表、聚合函數、投影查詢 
from  類名  
inner join 類
where 條件  
group  by 屬性名稱 having 條件 
order by 屬性名稱 desc/asc  

(2)查詢語句示例
① 查詢所有數據
查詢學生表的所有學生對象:

from Student (不能寫成select * from Student)

② 投影查詢(查詢表的一部分字段或者聚合函數)
查詢學生表中的學生姓名屬性:

select name from Student;
當查詢的是單個屬性時,查詢的集合中保存的就是該屬性值

查詢學生表中的學生姓名和年齡:

selectname,age from Student ;
當查詢的是多個屬性時,查詢的集合中保存的是Object 數組,一個數組表示一行數據

查詢學生表中的學生姓名和年齡並封裝爲學生類對象:

select new Student(name,age)from Student
學生類中需要提供對應的帶參構造函數

(3)where子句:別名需要加as
where子句可以對數據進行篩選,查詢出滿足條件的數據,具體的條件判斷方式和SQL類似。

><>=<==<>、is null、 is not null、 in、 between and、like

group by having子句:分組子句用法和SQL一致
order by子句:排序子句用法和SQL一致

3、HQL 使用過程

(1)創建Query對象:

Query query=session.creatQuery(hql);
  • 使用:參數名稱作爲佔位符以後可以使用query.setParameter(“參數名稱”,值)或者query.setXxx(“參數名稱”,值);的方式來爲佔位符賦值
  • 使用:參數名稱作爲佔位符以後還可以使用query.setProperties(Map map)以及query.setProperties(實體類對象)的方式來爲所有命名參數同時賦值,使用鍵值對需要保證鍵和命名參數名稱一致,使用實體類需要保證命名參數名稱與實體類屬性一致。

(2)分頁查詢
如果要分頁查詢在執行查詢前需要先執行兩個方法:

query.setFirstResult(); 設置起始查詢位置
query.setMaxResult(); 設置每頁顯示總數

查詢數據並將查詢出的結果封裝爲集合:

query.getList();

查詢數據並將查詢出的數據封裝爲一個實體類對象:

query.uniqueResult();

Demo:HQL 查詢示例

public class HQLQuery {
	public static void main(String[] args) {
		Session session = SessionUtil.openConnection();
		
		//1、查詢所有數據
		Query<Products> query = session.createQuery("from Products", Products.class);
		List<Products> list = query.list();
		for(Products p: list) {
			System.out.println(p);
		}
		//2、投影查詢:查詢單個字段
		Query<String> query1 = session.createQuery("select p_name from Products", String.class);
		List<String> list1 = query1.list();
		for(String p: list1) {
			System.out.println(p);
		}
		//3、投影查詢:查詢單個對象封裝成類對象
		Query<Products> query2 = session.createQuery("select new Products(p_name) from Products", Products.class);
		List<Products> list2 = query2.list();
		for(Products p: list2) {
			System.out.println(p);
		}
		//4、投影查詢:查詢聚合函數單個結果
		Query<Long> query3 = session.createQuery("select count(p_id) from Products", Long.class);
		Long list3 = query3.uniqueResult();
		System.out.println(list3);
		
		//5、投影查詢:查詢多個字段,封裝成Object數組
		Query<Object[]> query4 = session.createQuery("select p_name, p_price from Products", Object[].class);
		List<Object[]> list4 = query4.list();
		for(Object[] p: list4) {
			System.out.println(p[0] + "," + p[1]);
		}
		//6、查詢多個結果封裝成鍵值對(必須要給屬性取別名)
		Query query5=session.createQuery("select p_name as name,p_price as price from Products");
		query5.unwrap(QueryImpl.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
		List<Map> list5 = query5.list();
		for(Map row:list5) {
			for(Object key:row.keySet()) {
				System.out.print(key+":"+row.get(key));
			}
			System.out.println("");
		}
		//7、將投影查詢的多個結果封裝爲實體類對象
		Query<Products> query6 = session.createQuery("select new Products(p_name, p_price) from Products",Products.class);
		List<Products> list6 = query6.list();
		for(Products p: list6) {
			System.out.println(p);
		}
		//8、條件查詢:查詢價格在200塊以下,庫存在1000以下的商品
		Query<Products> query7 = session.createQuery("from Products where p_price < :p_price and p_count < :p_count", Products.class);
		//第一種給命名參數賦值的方式
		query7.setParameter("p_price", 2000.0);
		query7.setParameter("p_count", 1000);
		//第二種給命名參數賦值的方式
//		Map<String,Object> map = new HashMap<String, Object>();
//		map.put("p_price", 2000.0);
//		map.put("p_count", 1000);
//		query7.setProperties(map);
		List<Products> list7 = query7.list();
		for(Products p: list7) {
			System.out.println(p);
		}
		//9、將查詢結果排序
		Query<Products> query8 = session.createQuery("from Products where p_price < :price and p_count < :count order by p_id desc", Products.class);
		query8.setParameter("price", 2000.0);
		query8.setParameter("count", 1000);
		List<Products> list8 = query8.list();
		for(Products p: list8) {
			System.out.println(p);
		}
		//10、分頁查詢
		Query<Products> query9 = session.createQuery("from Products where p_price < :price and p_count > :count order by p_id desc", Products.class);
		query9.setParameter("price", 2000.0);
		query9.setParameter("count", 1000);
		query9.setFirstResult(0);
		query9.setMaxResults(5);
		List<Products> list9 = query9.list();
		for(Products p:list9) {
			System.out.println(p);
		}
		//11、多表聯合查詢
		Query query10=session.createQuery("select p.p_id as id, p.p_name as name, p.p_price as price, p.p_count as count, t.lt_name as tname from Products as p inner join LType as t on p.p_typeid = t.lt_id");
		query10.unwrap(QueryImpl.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
		List list10 = query10.list();
		System.out.println(JSONArray.fromObject(list10).toString());
		
		session.close();
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章