一、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();
}
}