日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

Hibernate之检索方式(HQL/QBC/本地SQL)

發布時間:2025/3/20 数据库 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Hibernate之检索方式(HQL/QBC/本地SQL) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、概述

  • Hibernate提供了以下幾種檢索對象的方式

    • 導航對象圖:根據已經加載的對象導航到其它對象

    • OID:按照對象的OID來檢索對象

    • HQL:使用面向對象的HQL查詢語句

    • QBC:使用QBC(Query By Criteria)API來檢索對象

    • 本地SQL:使用本地數據庫的SQL查詢語句

二、HQL

  • HQL是面向對象的查詢語句,它有如下功能:

    • 在查詢語句中設定各種查詢條件

    • 支持投影查詢,即僅檢索出對象的部分屬性

    • 支持分頁查詢

    • 支持連接查詢

    • 支持分組查詢

    • 提供內置聚集函數

    • 支持子查詢

    • 支持動態綁定參數

    • 能夠調用用戶定義的SQL函數或標準的SQL函數

  • 步驟:

1.通過Session的createQuery()方法創建一個Query對象,它包括一個HQL查詢語句。HQL查詢語句中可以包含命名參數

2.動態綁定參數

3.調用Query相關方法執行查詢語句

  • Query接口支持方法鏈編程風格,它的setXxx()方法返回自身實例

  • 綁定參數

    • Hibernate的參數綁定機制依賴于JDBC API中的PreparedStatement的預定義SQL語句功能

    • HQL的參數綁定有兩種形式:

      • 按參數名字綁定:命名參數以“:”開頭

      • 按參數位置綁定:用"?"來定義參數位置

    • 相關方法:

      • setEntity():把參數與一個持久化類綁定

      • setParameter():綁定任意類型的參數,該方法的第三個參數顯示指定Hibernate映射類型

  • HQL采用ORDER BY關鍵字對查詢結果排序

實體類(對應的配置文件省略)

Department.java

public class Department { ?private Integer id;private String name;private Set<Employee> emps = new HashSet<>(); }

Employee.java

public class Employee { ?private Integer id;private String name;private float salary;private String email;public Employee() {}public Employee(String email, float salary, Department dept) {this.salary = salary;this.email = email;this.dept = dept;} ?///get(),set()方法 }

測試:

private SessionFactory sessionFactory;private Session session;private Transaction transaction;@Beforepublic void init(){Configuration configuration = new Configuration().configure();ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();sessionFactory = configuration.buildSessionFactory(serviceRegistry);session = sessionFactory.openSession();transaction = session.beginTransaction();}@Afterpublic void destroy(){transaction.commit();session.close();sessionFactory.close();} ?@Testpublic void testHQLNamedParameter(){//1. 創建 Query 對象//基于命名參數. String hql = "FROM Employee e WHERE e.salary > :sal AND e.email LIKE :email";Query query = session.createQuery(hql);//2. 綁定參數query.setFloat("sal", 7000).setString("email", "%A%");//3. 執行查詢List<Employee> emps = query.list();System.out.println(emps.size()); ?}@Testpublic void testHQL(){//1. 創建 Query 對象//基于位置的參數. String hql = "FROM Employee e WHERE e.salary > ? AND e.email LIKE ? AND e.dept = ? "+ "ORDER BY e.salary";Query query = session.createQuery(hql);//2. 綁定參數//Query 對象調用 setXxx 方法支持方法鏈的編程風格.Department dept = new Department();dept.setId(80); query.setFloat(0, 6000).setString(1, "%A%").setEntity(2, dept);//3. 執行查詢List<Employee> emps = query.list();System.out.println(emps.size()); ?}

分頁查詢

  • setFirstResult(int firstResult):設定從哪一個對象開始索引(起始值為0)

  • setMaxResults(int maxResults):設定一次最多索引出的對象的數目

@Testpublic void testPageQuery(){String hql = "FROM Employee";Query query = session.createQuery(hql);//當前頁int pageNo = 22;//每頁的記錄數int pageSize = 5;List<Employee> emps = query.setFirstResult((pageNo - 1) * pageSize).setMaxResults(pageSize).list();System.out.println(emps);}

在映射文件中定義命名查詢語句

  • Hibernate允許在映射文件中定義字符串形式的查詢語句

  • <query>元素用于定義一個HQL查詢語句,它和<class>元素并列

  • 在程序中通過Session的getNamedQuery()方法獲取查詢語句對應的Query對象

? ?<query name="salaryEmps"><![CDATA[FROM Employee e WHERE e.salary > :minSal AND e.salary < :maxSal]]></query> @Testpublic void testNamedQuery(){Query query = session.getNamedQuery("salaryEmps");List<Employee> emps = query.setFloat("minSal", 5000).setFloat("maxSal", 10000).list();System.out.println(emps.size()); }

投影查詢

  • 查詢結果僅包含實體的部分屬性,通過select關鍵字實現

  • list()方法返回的集合中包含的是數組類型的元素,每個對象數組代表查詢結果的一條記錄

  • 可以在持久化類中定義一個對象的構造器來包裝投影查詢返回的記錄

  • 可以通過distinct關鍵字來保證查詢結果不會返回重復元素

@Testpublic void testFieldQuery2(){String hql = "SELECT new Employee(e.email, e.salary, e.dept) "+ "FROM Employee e "+ "WHERE e.dept = :dept";Query query = session.createQuery(hql);Department dept = new Department();dept.setId(80);List<Employee> result = query.setEntity("dept", dept).list();for(Employee emp: result){System.out.println(emp.getId() + ", " + emp.getEmail() + ", " + emp.getSalary() + ", " + emp.getDept());}}@Testpublic void testFieldQuery(){String hql = "SELECT e.email, e.salary, e.dept FROM Employee e WHERE e.dept = :dept";Query query = session.createQuery(hql);Department dept = new Department();dept.setId(80);List<Object[]> result = query.setEntity("dept", dept).list();for(Object [] objs: result){System.out.println(Arrays.asList(objs));}}

報表查詢

  • 報表查詢用于對數據分組和統計

  • 在HQL查詢語句中可以調用以下聚集函數

    • count()

    • min()

    • max()

    • sum()

    • avg()

@Testpublic void testGroupBy(){String hql = "SELECT min(e.salary), max(e.salary) "+ "FROM Employee e "+ "GROUP BY e.dept "+ "HAVING min(salary) > :minSal";Query query = session.createQuery(hql).setFloat("minSal", 8000);List<Object []> result = query.list();for(Object [] objs: result){System.out.println(Arrays.asList(objs));}}

迫切左外連接

  • left join fetch關鍵字

  • list()方法返回的集合中存放實體對象的引用, 每個 Department 對象關聯的 Employee 集合都被初始化, 存放所有關聯的 Employee 的實體對象

  • 查詢結果中可能會包含重復元素, 可以通過一個 HashSet 來過濾重復元素

@Testpublic void testLeftJoinFetch(){ // String hql = "SELECT DISTINCT d FROM Department d LEFT JOIN FETCH d.emps";String hql = "FROM Department d INNER JOIN FETCH d.emps";Query query = session.createQuery(hql);List<Department> depts = query.list();depts = new ArrayList<>(new LinkedHashSet(depts));System.out.println(depts.size()); for(Department dept: depts){System.out.println(dept.getName() + "-" + dept.getEmps().size());}}

左外連接:

  • left join關鍵字

  • list()方法返回的集合中存放的是對象數組類型

  • 根據配置文件來決定Employee集合的檢索策略

  • 如果希望list()方法返回的集合中包含Department對象,可以在HQL查詢語句中使用select關鍵字

@Testpublic void testLeftJoin(){String hql = "SELECT DISTINCT d FROM Department d LEFT JOIN d.emps";Query query = session.createQuery(hql);List<Department> depts = query.list();System.out.println(depts.size());for(Department dept: depts){System.out.println(dept.getName() + ", " + dept.getEmps().size()); }// ? ? String hql = "FROM Department d LEFT JOIN d.emps"; // List<Object []> result = query.list(); // result = new ArrayList<>(new LinkedHashSet<>(result)); // System.out.println(result); // // for(Object [] objs: result){ // System.out.println(Arrays.asList(objs)); // }}

(迫切)內連接(原理同上)

@Testpublic void testLeftJoinFetch2(){String hql = "SELECT e FROM Employee e INNER JOIN e.dept";Query query = session.createQuery(hql);List<Employee> emps = query.list();System.out.println(emps.size()); for(Employee emp: emps){System.out.println(emp.getName() + ", " + emp.getDept().getName());}}

三、QBC

  • QBC查詢就是通過使用Hibernate提供的QBC API來查詢對象

@Testpublic void testQBC4(){Criteria criteria = session.createCriteria(Employee.class);//1. 添加排序criteria.addOrder(Order.asc("salary"));criteria.addOrder(Order.desc("email"));//2. 添加翻頁方法int pageSize = 5;int pageNo = 3;criteria.setFirstResult((pageNo - 1) * pageSize).setMaxResults(pageSize).list();}@Testpublic void testQBC3(){Criteria criteria = session.createCriteria(Employee.class);//統計查詢: 使用 Projection 來表示: 可以由 Projections 的靜態方法得到criteria.setProjection(Projections.max("salary"));System.out.println(criteria.uniqueResult()); }@Testpublic void testQBC2(){Criteria criteria = session.createCriteria(Employee.class);//1. AND: 使用 Conjunction 表示//Conjunction 本身就是一個 Criterion 對象//且其中還可以添加 Criterion 對象Conjunction conjunction = Restrictions.conjunction();conjunction.add(Restrictions.like("name", "a", MatchMode.ANYWHERE));Department dept = new Department();dept.setId(80);conjunction.add(Restrictions.eq("dept", dept));//name like "%a%" and dept=Department [id=80]System.out.println(conjunction); //2. ORDisjunction disjunction = Restrictions.disjunction();disjunction.add(Restrictions.ge("salary", 6000F));disjunction.add(Restrictions.isNull("email"));//salary>=6000 or email is nullSystem.out.println(disjunction); //上述的兩個條件用and連接起來criteria.add(disjunction);criteria.add(conjunction);criteria.list();}@Testpublic void testQBC(){//1. 創建一個 Criteria 對象Criteria criteria = session.createCriteria(Employee.class);//2. 添加查詢條件: 在 QBC 中查詢條件使用 Criterion 來表示//Criterion 可以通過 Restrictions 的靜態方法得到criteria.add(Restrictions.eq("email", "SKUMAR"));criteria.add(Restrictions.gt("salary", 5000F));//3. 執行查詢Employee employee = (Employee) criteria.uniqueResult();System.out.println(employee); }

四、本地SQL

@Testpublic void testNativeSQL(){String sql = "INSERT INTO gg_department VALUES(?, ?)";Query query = session.createSQLQuery(sql);query.setInteger(0, 280).setString(1, "ATGUIGU").executeUpdate();}

?

總結

以上是生活随笔為你收集整理的Hibernate之检索方式(HQL/QBC/本地SQL)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。