在Hibernate當中提供了多種查詢方式。Hibernate一共提供了五中查詢方式。
準備工作
假設我們現在有兩個對象
客戶----聯繫人
配置Hibernate工具類
public class HibernateUtils {
public static final Configuration cfg;
public static final SessionFactory sf;
static {
cfg = new Configuration().configure();// 獲取與數據庫的鏈接的配置文件
sf = cfg.buildSessionFactory();//開啓事務建立與數據庫之間的鏈接
}
public static Session openSession() {
return sf.openSession();
}
public static Session getCurrentSession() {
return sf.getCurrentSession();
}
}
Hibernate的查詢方式
1、Hibernate的查詢方式:OID查詢
OID檢索:HIbernate根據對象的OID(主鍵)進行檢索。
A:使用GET方法
Customer代表客戶的意思(封裝的數據庫當中表的對象)
Customer customer = session.get(Customer.class,1l);//OID 檢索,通過ID查詢對應的對象的數據
B:使用load方法
Customer customer = session.load(Customer.class,1l);//OID 檢索,通過ID查詢對應的對象的數據
2、Hibernate的查詢方式:對象導航檢索
對象導航檢索:Hibernate根據一個已經查詢到的對象,去獲得其關聯的對象的一種查詢方式。
在Hibernate當中可以這樣使用
LinkMan linkMan= session.load(LinkMan.class,1l);//OID 檢索,通過ID查詢對應的對象的數據
Customer customer = linkMan.getCustomer();//獲得到聯繫人關聯的對象(包括客戶)
Customer customer = session.get(Customer.class,2l);//OID 檢索,通過ID查詢對應的對象的數據
Set<LinkMan> linkMans = customer.getLinkMans();//通過對象獲取到集合
3、Hibernate的查詢方式:HQL檢索
HQL查詢:Hibernate Query Language:Hibernate的查詢語言,是一種面向對象的一種查詢語言,語法類似SQL。
通過session.createQuery();
用於接收HQL進行的一種查詢方式。
Hibernate環境搭建和配置另一篇文章
https://blog.csdn.net/qq_44757034/article/details/106242492
A、初始化一些數據
/*
* HQL 的查詢方式的測試類
*/
public class HibernateDemo1 {
@Test
// 初始化數據
public void demo01() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
// 創建一個客戶
Customer customer = new Customer();
customer.setCust_name("李冰");
for (int i = 1; i <= 10; i++) {
LinkMan linkMan = new LinkMan();
linkMan.setLkm_name("小花" + i);
linkMan.setCustomer(customer);
customer.getLinkMans().add(linkMan);
session.save(linkMan);
}
session.save(customer);
transaction.commit();
}
}
初始化三組聯繫人和客戶
B、HQL的簡單查詢
(1)HQL的簡單查詢
兩個對象相互包含的時候注意toString,最好不要寫對象的集合,因爲這是個死循環
@Test
// HQL的簡單查詢
public void demo02() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
//得到所有的客戶
Query query = session.createQuery("from Customer");
List<Customer> list = query.list();
for (Customer customer : list) {
System.out.println(customer);
}
transaction.commit();
}
注意SQL當中支持*號的寫法:例如 :select * from cst_customer
,但是在HQL當中不支持 * 的寫法。
Query query = session.createQuery("from * Customer");//是錯誤的寫法,運行代碼時會報錯
也可以這樣查詢
(2.0)HQL別名查詢
@Test
// 別名查詢
public void demo03() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
// 得到所有的客戶
//別名查詢
Query query = session.createQuery("from Customer c");//c是Customer的別名
List<Customer> list = query.list();
for (Customer customer : list) {
System.out.println(customer);
}
transaction.commit();
}
(2.1)HQL別名查詢
@Test
// 別名查詢
public void demo03() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
// 得到所有的客戶
//別名查詢
Query query = session.createQuery("select c from Customer c");//c是Customer
List<Customer> list = query.list();
for (Customer customer : list) {
System.out.println(customer);
}
transaction.commit();
}
C:HQL的排序查詢
(1)默認排序:升序排序
@Test
// 排序查詢
public void demo04() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
// 得到所有的客戶
// 排序查詢
List<Customer> list = session.createQuery("from Customer order by cust_id").list();// c是Customer
for (Customer customer : list) {
System.out.println(customer);
}
transaction.commit();
}
(2)設置降序排序
@Test
// 排序查詢
public void demo04() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
// 得到所有的客戶
// 降序查詢
List<Customer> list = session.createQuery("from Customer order by cust_id desc").list();// c是Customer
for (Customer customer : list) {
System.out.println(customer);
}
transaction.commit();
}
升序使用asc降序使用desc
D:HQL的條件查詢
(一)按位置綁定:根據參數的位置進行綁定。
(1)一個條件
@Test
// 條件查詢
public void demo05() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
// 條件查詢
// 一、按位置綁定
Query query = session.createQuery("from Customer where cust_name = ?");// c是Customer
query.setParameter(0, "李冰");
List<Customer> list = query.list();
// 二、按名稱綁定
for (Customer customer : list) {
System.out.println(customer);
}
transaction.commit();
}
(2)多個條件(模糊查詢)
@Test
// 條件查詢
public void demo05() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
// 條件查詢
// 一、按位置綁定
Query query = session.createQuery("from Customer where cust_source = ? and cust_name like ?");
query.setParameter(0, "小廣告");
query.setParameter(1, "李%");
List<Customer> list = query.list();
for (Customer customer : list) {
System.out.println(customer);
}
transaction.commit();
}
(二)按名稱綁定匿名名稱
@Test
// 條件查詢
public void demo05() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
// 條件查詢
// 二、按名稱綁定
Query query = session.createQuery("from Customer where cust_source = :aaa and cust_name like :bbb");
//設置參數
query.setParameter("aaa", "朋友推薦");
query.setParameter("bbb", "李%");
List<Customer> list = query.list();
for (Customer customer : list) {
System.out.println(customer);
}
transaction.commit();
}
E:HQL的投影查詢
投影查詢:指的是查詢對象的某個或某些屬性。
(1)單個屬性投影查詢
@Test
// 投影查詢
public void demo06() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
// 投影查詢,查詢當中的一個屬性
List<Object> list = session.createQuery("select c.cust_name from Customer c").list();
for (Object object : list) {
System.out.println(object);
}
transaction.commit();
}
(2)多個屬性投影查詢
@Test
// 投影查詢
public void demo06() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
// 投影查詢,查詢當中的一個屬性
List<Object[]> list = session.createQuery("select c.cust_name,c.cust_source from Customer c").list();
for (Object[] objects : list) {
System.out.println(Arrays.toString(objects));
}
transaction.commit();
}
(3)查詢多個屬性分裝到對象當中投影查詢
先對要查詢的對象寫入構造方法
@Test
// 投影查詢
public void demo06() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
// 查詢多個屬性,分裝到對象當中
List<Customer> list = session.createQuery("select new Customer(cust_name,cust_source) from Customer").list();
for (Customer customer : list) {
System.out.println(customer);
}
transaction.commit();
}
F:HQL的分頁查詢
@Test
// 分頁查詢
public void demo07() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
// 分頁查詢
Query query = session.createQuery("from LinkMan");
query.setFirstResult(0);
query.setFirstResult(10);
List<LinkMan> list = query.list();
for (LinkMan linkMan : list) {
System.out.println(linkMan);
}
transaction.commit();
}
注意在LinkMan當中也要生成對應的toString 方法
G:HQL的分組統計查詢
(1)分組查詢
@Test
// 分組統計查詢
public void demo08() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
//聚合函數的使用:聚合函數包括:count(),max(),min(),avg(),sum()
//代表唯一結果uniqueResult
Object object = session.createQuery("select count(*) from Customer").uniqueResult();
System.out.println(object);
transaction.commit();
}
(2)分組統計(按照客戶的來源統計客戶的個數)
SQL語句:SELECT cust_source,COUNT(*) FROM cst_customer GROUP BY cust_source;
轉換HQL將字段變爲屬性,把表的地方變爲對象
@Test
// 分組統計查詢
public void demo08() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
List<Object[]> list = session.createQuery("select cust_source,count(*) from Customer group by cust_source").list();//代表唯一結果uniqueResult
for (Object[] objects : list) {
System.out.println(Arrays.toString(objects));
}
transaction.commit();
}
限定條件
SQL語句:SELECT cust_source,COUNT(*) FROM cst_customer GROUP BY cust_source HAVING count(*) >= 2;
@Test
// 分組統計查詢
public void demo08() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
List<Object[]> list = session.createQuery("select cust_source,count(*) from Customer group by cust_source HAVING count(*) >= 2").list();//代表唯一結果uniqueResult
for (Object[] objects : list) {
System.out.println(Arrays.toString(objects));
}
transaction.commit();
}
總結聚合函數
聚合函數的使用:聚合函數包括:count(),max(),min(),avg(),sum()
聚合函數 count(),求數據表的行數
select count(*/字段名) from 數據表
聚合函數 max(),求某列的最大數值
select max(字段名)from 數據表
聚合函數min(),求某列的最小值
select main(字段名) from 數據表
聚合函數sum(),對數據表的某列進行求和操作
select sum(字段名) from 數據表
聚合函數avg(),對數據表的某列進行求平均值操作
select avg(字段名) from 數據表
聚合函數和分組一起使用
select count(*),group_concat(age) from students group by age;
F:HQL的多表查詢
a、SQL當中的多表查詢
連接查詢
i、交叉連接:笛卡爾積
# A,B 代表兩個表,,這種查詢方式一般不用
select * from A,B;
ii、內鏈接 : inner join
(inner可以省略) 內鏈接查到的是兩個表的交
{
隱式內鏈接 :
# A 和 B 是兩個表 A.id和B.id 分別對應兩個表的關聯字段
select * from A,B where A.id=B.id;
顯示內鏈接 :
# A 和 B 是兩個表 A.id和B.id 分別對應兩個表的關聯字段
select * from A inner join B on A.id = B.id;
}
iii、外鏈接 外鏈接查詢到的是兩個表的交集以及left 或right對應的數據
{
左外鏈接 :left outer join(outer 可以省略)
select * from A left outer join B on A.id = B.id;
右外鏈接 : right outer join(outer 可以省略)
select * from A right outer join B on A.id = B.id;
}
b、HQL當中的多表查詢
鏈接查詢
交叉連接
內鏈接
顯式內連接:封裝成爲數組
隱式內連接 from Customer c inner join c.linkMans
:封裝成爲數組
@Test
// HQL多表的查詢
public void demo09() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
// SQL:SELECT * FROM cst_customer c INNER JOIN cst_linkman l ON c.cust_id =
// l.lkm_cust_id;
// HQL的內連接:from Customer c inner join c.linkMans
Query createQuery = session.createQuery("from Customer c inner join c.linkMans");
List<Object[]> list = createQuery.list();
for (Object[] objects : list) {
System.out.println(Arrays.toString(objects));
}
transaction.commit();
}
迫切內連接:(會將當前表外鍵對應的另外一個表當中的的數據都分裝當中當前表對應的對象當中)封裝成爲對象
@Test
// HQL多表的查詢
public void demo09() {
Session session = HibernateUtils.getCurrentSession();//建立連接
Transaction transaction = session.beginTransaction();//開啓事務
// SQL:SELECT * FROM cst_customer c INNER JOIN cst_linkman l ON c.cust_id =
// l.lkm_cust_id;
// HQL:迫切內連接 其實就是在普通的內連接inner join後添加一個關鍵字叫fetch --> from Customer c inner join
// fetch c.linkMans
// fetch通知Hibernate,將另一個對象的數據封裝到該對象當中,也就是前面的對象當中(將LinkMan當中的數據放到Customer當中)
List<Customer> list = session.createQuery("from Customer c inner join fetch c.linkMans").list();
for (Customer customer : list) {
System.out.println(customer);
}
transaction.commit();
}
獲取到的內容是將LinkMan當中的東西分裝到了Customer當中,並且數據冗餘
改進上述查詢方式 關鍵詞 DISTINCT 用於返回唯一不同的值。
SELECT DISTINCT 列名稱 FROM 表名稱
@Test
// HQL多表的查詢
public void demo09() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
// SQL:SELECT * FROM cst_customer c INNER JOIN cst_linkman l ON c.cust_id =
// l.lkm_cust_id;
// HQL:迫切內連接 其實就是在普通的內連接inner join後添加一個關鍵字叫fetch --> from Customer c inner join
// fetch c.linkMans
// fetch通知Hibernate,將另一個對象的數據封裝到該對象當中,也就是前面的對象當中(將LinkMan當中的數據放到Customer當中)
List<Customer> list = session.createQuery("select distinct c from Customer c inner join fetch c.linkMans").list();
for (Customer customer : list) {
System.out.println(customer);
}
transaction.commit();
}
外鏈接
左外連接:封裝成數組
右外連接:封裝成數組
迫切左外連接:封裝成對象
4、Hibernate的查詢方式:QBC檢索
QBC查詢:Query By Criteria,叫做條件查詢。是一種更加面向對象化的查詢方式。
Criteria是一種比hql更面向對象的查詢方式
(1)簡單查詢
通過session或者Criteria對象
criteria對象獲取集合
@Test
// 簡單的查詢
public void demo01() {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
// 獲得Criteria的對象
Criteria criteria = session.createCriteria(Customer.class);
List<Customer> list = criteria.list();
for (Customer customer : list) {
System.out.println(customer);
}
tx.commit();
}
(2)排序查詢 criteria.addOrder(Order.條件)添加排序
a、升序排序
@Test
public void demo02() {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
Criteria criteria = session.createCriteria(Customer.class);
criteria.addOrder(Order.asc("cust_id"));//升序
List<Customer> list = criteria.list();
for (Customer customer : list) {
System.out.println(customer);
}
tx.commit();
}
b、降序排序
@Test
public void demo02() {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
Criteria criteria = session.createCriteria(Customer.class);
criteria.addOrder(Order.desc("cust_id"));//降序
List<Customer> list = criteria.list();
for (Customer customer : list) {
System.out.println(customer);
}
tx.commit();
}
(3)分頁查詢
@Test
public void demo03() {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
Criteria criteria = session.createCriteria(LinkMan.class);
criteria.setFirstResult(0);
criteria.setMaxResults(10);
List<LinkMan> list = criteria.list();
for (LinkMan linkMan : list) {
System.out.println(linkMan);
}
tx.commit();
}
(4)條件查詢 add(Restrictions…) 限定條件
@Test
// 條件查詢
public void demo04() {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
// 條件查詢
Criteria criteria = session.createCriteria(Customer.class);
// 設置條件
//= eq
//> gt
//< ge
//< lt
//<= le
//<> ne
//like
//in
//and
//or
criteria.add(Restrictions.eq("cust_source", "小廣告"));
List<Customer> list = criteria.list();
for (Customer customer : list) {
System.out.println(customer);
}
tx.commit();
}
多條件查詢
@Test
// 多條件查詢
public void demo04() {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
// 條件查詢
Criteria criteria = session.createCriteria(Customer.class);
// 設置條件
//= eq
//> gt
//< ge
//< lt
//<= le
//<> ne
criteria.add(Restrictions.eq("cust_source", "小廣告"));
criteria.add(Restrictions.like("cust_name", "李%"));
List<Customer> list = criteria.list();
for (Customer customer : list) {
System.out.println(customer);
}
tx.commit();
}
(5)統計分組查詢
setProjection 方法用於設置查詢的投影列。
該方法與 Projections 類結合不僅可以實現簡單的投影查詢,而且可以實現數據的分組統計。
@Test
// 統計查詢
public void demo05() {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
//先獲取到要查詢對象(Customer)的criteria
Criteria criteria = session.createCriteria(Customer.class);
/*
* add :普通條件在where後面的條件
* addOrder : 排序
* setProgect(); :聚合函數和group by having
*/
criteria.setProjection(Projections.rowCount());
Long num = (Long) criteria.uniqueResult();
System.out.println(num);
//從數據庫當中活動
tx.commit();
}
(6)離線條件查詢(SSH)—DetachedCriteria
在Web層創建該對象
以下是簡略步驟
DetachedCriteria dc = DetachedCriteria.forClass(Customer.class);
dc.add(Restrictions.eq())://設置條件
service.query(dc);
然後將dc該對象傳入到業務層(dao層)
dao.query(dc);
以上是離線的,然後要在dao層與數據庫建立連接
//綁定session
criteria.list();
實際操作:(離線條件查詢)
@Test
// 離線條件查詢
public void demo06() {
//=============假設這裏是Web層
DetachedCriteria criteria = DetachedCriteria.forClass(Customer.class);
//Restrictions限定
criteria.add(Restrictions.ilike("cust_name", "李%"));
//=============
//==================dao
Session session = HibernateUtils.getCurrentSession();//建立連接
Transaction tx = session.beginTransaction();//開啓事務
Criteria executableCriteria = criteria.getExecutableCriteria(session);//獲得一個可執行的criteria(標準)對象
List<Customer> list = executableCriteria.list();
for (Customer customer : list) {
System.out.println(customer);
}
tx.commit();//提交事務
}
5、Hibernate的查詢方式:SQL檢索
SQL查詢:通過使用SQL語句進行查詢。
(1)查詢到的結果封裝到數組當中
public class HibernateDemo03 {
@Test
// SQL 查詢
public void demo01() {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
SQLQuery sqlQuery = session.createSQLQuery("select * from cst_customer");
List<Object[]> list = sqlQuery.list();
for (Object[] lists : list) {
System.out.println(Arrays.toString(lists));
}
tx.commit();
}
}
(2)查詢到的結果封裝到對象當中
public class HibernateDemo03 {
@Test
// SQL 查詢
public void demo01() {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
SQLQuery sqlQuery = session.createSQLQuery("select * from cst_customer");
sqlQuery.addEntity(Customer.class);
List<Customer> list = sqlQuery.list();
for (Customer customer : list) {
System.out.println(customer);
}
tx.commit();
}
}