Hibernate查詢方式
Hibernate查詢方式
OID查詢
它就是根據id查詢一個實體
涉及的方法:
get(Class clazz,Serializable id):引數1是要查詢的實體位元組碼,引數2:是要查詢的id。
load(Class clazz,Serializable id):引數1是要查詢的實體位元組碼,引數2:是要查詢的id。
Hibernate的檢索策略
類級別檢索策略:
get方法:
它永遠都是立即載入。返回的物件是實體類型別。
立即載入的含義:不管用不用,都馬上發起查詢。
load方法:
它預設是延遲載入。返回的是實體類物件的代理物件。
它可以通過配置的方式改為立即載入。配置的位置是對映檔案的class標籤。
涉及的屬性是:lazy。含義就是是否延遲載入。 取值true延遲載入(預設值) false不是延遲載入
延遲載入的含義:什麼時候用,什麼時候真正發起查詢。
測試OID檢索方式
- package com.pc.hibernate.test.querymethod;
- import org.hibernate.Session;
- import org.hibernate.Transaction;
- import org.junit.Test;
- import com.pc.hibernate.domain.Customer;
- import com.pc.hibernate.utils.HibernateUtils;
- /**
- * Hibernate中的查詢方式:
- * OID查詢:
- * 它就是根據id查詢一個實體
- * 涉及的方法:
- * get(Class clazz,Serializable id):引數1是要查詢的實體位元組碼,引數2:是要查詢的id。
- * load(Class clazz,Serializable id):引數1是要查詢的實體位元組碼,引數2:是要查詢的id。
- *
- * Hibernate的檢索策略
- * 類級別檢索策略:
- * get方法:
- * 它永遠都是立即載入。返回的物件是實體類型別。
- * 立即載入的含義:不管用不用,都馬上發起查詢。
- * load方法:
- * 它預設是延遲載入。返回的是實體類物件的代理物件。
- * 它可以通過配置的方式改為立即載入。配置的位置是對映檔案的class標籤。
- * 涉及的屬性是:lazy。含義就是是否延遲載入。 取值true延遲載入(預設值) false不是延遲載入
- * 延遲載入的含義:什麼時候用,什麼時候真正發起查詢。
- * @author Switch
- *
- */
- public class TestOIDQuery {
- /**
- * 需求:
- * 查詢id為1的客戶
- */
- @Test
- public void test1() {
- Session session = HibernateUtils.getCurrentSession();
- Transaction transaction = session.beginTransaction();
- Customer customer = session.get(Customer.class, 1L);
- transaction.commit();
- // 輸出1和客戶資訊
- System.out.println(customer.getCustId());
- System.out.println(customer);
- }
- /**
- * 需求:
- * 查詢id為1的客戶
- */
- @Test
- public void test2() {
- Session session = HibernateUtils.getCurrentSession();
- Transaction transaction = session.beginTransaction();
- Customer customer = session.load(Customer.class, 1L);
- transaction.commit();
- // 輸出1和報錯could not initialize proxy - no Session
- // 當<class name="Customer" table="cst_customer" lazy="false">時
- // 該方法正確,因為這時候已經不延遲載入了
- System.out.println(customer.getCustId());
- System.out.println(customer);
- }
- }
物件導航查詢
物件圖導航檢索方式是根據己經載入的物件,導航到他的關聯物件 。它利用類與類之間的關係來檢索物件 。譬如要查詢一個聯絡人對應的客戶,就可以由聯絡人物件自動導航找到聯絡人所屬的客戶物件。當然,前提是必須在物件關係對映檔案上配置了多對一的關係。
當我們兩個實體類有關聯關係時(一對多,多對一等等),在獲取一個實體時,可以根據物件的方法,獲取該實體關聯物件的資料。
customer.getLinkMans();獲取當前客戶下的所有聯絡人
linkman.getCustomer();獲取當前聯絡人所屬客戶。
- package com.pc.hibernate.test.querymethod;
- import java.util.List;
- import java.util.Set;
- import org.hibernate.SQLQuery;
- import org.hibernate.Session;
- import org.hibernate.Transaction;
- import org.junit.Test;
- import com.pc.hibernate.domain.Customer;
- import com.pc.hibernate.domain.LinkMan;
- import com.pc.hibernate.utils.HibernateUtils;
- /**
- *
- * Hibernate中的查詢方式:
- * 物件導航查詢
- * 當我們兩個實體類有關聯關係時(一對多,多對一等等),在獲取一個實體時,可以根據物件的方法,獲取該實體關聯物件的資料。
- * customer.getLinkMans();獲取當前客戶下的所有聯絡人
- * linkman.getCustomer();獲取當前聯絡人所屬客戶。
- *
- * @author Switch
- */
- public class TestObjectNavigationQuery {
- /**
- * 一般情況下我們都會有一個這樣的方法:根據id查詢一個實體。
- * 任何實體都應該有這麼個方法
- */
- public Customer findById(Long custId){
- Session s = HibernateUtils.getCurrentSession();
- Transaction tx = s.beginTransaction();
- Customer c1 = s.get(Customer.class, custId);
- tx.commit();
- return c1;
- }
- /**
- * 根據客戶id查詢聯絡人資訊
- * @param custId
- * @return
- */
- public List<LinkMan> findLinkManByCid(Long custId){
- Session s = HibernateUtils.getCurrentSession();
- Transaction tx = s.beginTransaction();
- SQLQuery query = s.createSQLQuery("select * from cst_linkman where lkm_cust_id = ? ");
- query.setLong(0, custId);
- query.addEntity(LinkMan.class);
- @SuppressWarnings("unchecked")
- List<LinkMan> mans = query.list();
- tx.commit();
- return mans;
- }
- /**
- * 需求:
- * 查詢id為1的客戶下的所有聯絡人
- */
- @Test
- public void test1(){
- // 傳統的使用方式
- List<LinkMan> list = findLinkManByCid(1L);
- System.out.println(list);
- Customer c = findById(1L);
- //物件導航查詢
- // 需要將Customer上對應於LinkMan的關係檢索策略的懶載入關閉
- Set<LinkMan> linkmans = c.getLinkMans();
- for(LinkMan linkMan : linkmans){
- System.out.println(linkMan);
- }
- }
- /**
- * 需求:
- * 查詢id為5的聯絡人所屬客戶
- */
- @Test
- public void test2() {
- Session session = HibernateUtils.openSession();
- Transaction transaction = session.beginTransaction();
- LinkMan linkMan = session.get(LinkMan.class, 5L);
- // 物件導航查詢
- System.out.println(linkMan.getCustomer());
- transaction.commit();
- }
- }
HQL查詢
HQL (Hibernate Query Language ) 是物件導向的查詢語言,它和 SQL 查詢語言有些相似 ,但它使用的是類、物件和屬性的概念 ,而沒有表和欄位的概念 。在Hibernate提供的各種檢索方式中 ,HQL是官方推薦的查詢語言,也是使用最廣泛的一種檢索 方式。
涉及的物件:
Query
如何獲取Query:
session.createQuery(String hql);
HQL語句寫法:
表名用實體類名稱替代
欄位名用實體類屬性名稱(get/set方法後面的部分,並且把首字母轉小寫)
Hibernate 進行 多表查詢與 SQL 其實是很相似的 ,但是 HQL 會在原來 SQL 分類的基礎上又多出來一些操作 。
HQL 的多表連線查詢的分類如下 :
- 交叉連線
- 內連線
- 顯式內連線
- 隱式內連線
- 迫切內連線
- 外連線
- 左外連線
- 迫切左外連線
其實這些連線查詢語法大致都是一致的,就是HQL查詢的是物件而SQL查詢的是表。那麼我們來比較一下SQL和HQL的連線查詢。
SQL 連線查詢
- SELECT * FROM cst_customer c INNER JOIN cst_linkman 1 ON c.cust_id = l.lkm_cust_id;
HQL 連線的查詢
- from Customer c inner join c.linkMans
在HQL中,我們不用寫關聯宇段了,因為客戶中的聯絡人的集合其實對應的就是外來鍵,所以我們在inner join的後面直接可以寫 c.linkMans。
迫切內連線其實就是在內連線的inner join後新增一個fetch關鍵字。
- from Customer c inner join fetch c.linkMans
內連線或是迫切內連線傳送的底層SQL都是一樣的,而且在生成的SQL語句中也沒有fetch關鍵字,當然fetch本身就不是SQL語句的關鍵字。所以一定要注意,fetch只能在HQL中使用的,生成了SQL語句以後,fetch就消失了 。
其實HQL內連線查詢的和SQL的內連線查詢到的結果集是一樣的 ,都是兩個表的交集部分的資料。
然後在封裝資料的時候,普通內連線會將屬於客戶的資料封裝到Customer物件中,會將屬於聯絡人的資料封裝到LinkMan物件中,所以每條記錄都會是裝有兩個物件的集合,所以封裝以後的資料是 List<Object[ ]>,在Object[ ]中有兩個物件一個是 Customer另一個是 LinkMan 。
那麼加了fetch以後,雖然查詢到的資料是一樣的,但是Hibernate發現HQL中有fetch就會將資料封裝到一個物件中,把屬於客戶的資料封裝到Customer物件中,將屬於聯絡人的部分封裝到Customer中的聯絡人的集合中,這樣最後封裝完成以後是一個 List<Customer> 中。
測試HQL方式
- package com.pc.hibernate.test.querymethod;
- import java.util.List;
- import org.hibernate.Query;
- import org.hibernate.Session;
- import org.hibernate.Transaction;
- import org.junit.Test;
- import com.pc.hibernate.domain.Customer;
- import com.pc.hibernate.domain.LinkMan;
- import com.pc.hibernate.utils.HibernateUtils;
- /**
- * Hibernate中的查詢方式:
- * HQL查詢:
- * 它是使用HQL語句進行查詢的。 HQL:Hiberante Query Language
- * 涉及的物件:
- * Query
- * 如何獲取Query:
- * session.createQuery(String hql);
- * HQL語句寫法:
- * 表名用實體類名稱替代
- * 欄位名用實體類屬性名稱(get/set方法後面的部分,並且把首字母轉小寫)
- *
- * @author Switch
- */
- public class TestHQLQuery {
- /**
- * 查詢所有
- * 需求:查詢所有客戶
- */
- @Test
- public void test1() {
- Session session = HibernateUtils.openSession();
- Transaction transaction = session.beginTransaction();
- // 查詢所有客戶
- Query query = session.createQuery("from Customer");
- @SuppressWarnings("unchecked")
- List<Customer> customers = query.list();
- transaction.commit();
- for (Customer customer : customers) {
- System.out.println(customer);
- }
- }
- /**
- * 條件查詢:
- * 需求:
- * 查詢客戶級別是23的,客戶名稱帶有 集 字的
- * 給HQL語句加條件用where
- * HQL語句的引數佔位符也可以使用?
- * hibernate中,引數佔位符是從0開始的。
- */
- @Test
- public void test2(){
- Session session = HibernateUtils.openSession();
- Transaction transaction = session.beginTransaction();
- // 查詢客戶級別是23的,客戶名稱帶有 集 字的
- Query query = session.createQuery("from Customer where custLevel = ? and custName like ?");
- query.setString(0, "23");
- query.setString(1, "%集%");
- @SuppressWarnings("unchecked")
- List<Customer> customers = query.list();
- transaction.commit();
- for (Customer customer : customers) {
- System.out.println(customer);
- }
- }
- /**
- * 具名查詢:
- * 給引數佔位符提供一個具體的名稱
- * HQL語句中的寫法:
- * 需要使用 :引數名稱
- * 例如: :custLevel :custName
- * 引數站位符賦值的寫法:
- * 需要注意:此處不能寫冒號,直接寫冒號後面的部分
- */
- @Test
- public void test3(){
- Session session = HibernateUtils.openSession();
- Transaction transaction = session.beginTransaction();
- // 查詢客戶級別是23的,客戶名稱帶有 集 字的
- // 給引數佔位符提供一個具體的名稱
- Query query = session.createQuery("from Customer where custLevel = :custLevel and custName like :custName");
- query.setString("custLevel", "23");
- query.setString("custName", "%集%");
- @SuppressWarnings("unchecked")
- List<Customer> customers = query.list();
- transaction.commit();
- for (Customer customer : customers) {
- System.out.println(customer);
- }
- }
- /**
- * 排序查詢:
- * 使用HQL語句,給查詢結果排序
- *
- * HQL語句中的排序:
- * order by
- * asc:升序(預設值)
- * desc:降序
- */
- @Test
- public void test4(){
- Session session = HibernateUtils.openSession();
- Transaction transaction = session.beginTransaction();
- // 按聯絡人ID降序排序聯絡人
- Query query = session.createQuery("from LinkMan order by lkmId desc");
- @SuppressWarnings("unchecked")
- List<LinkMan> linkMans = query.list();
- transaction.commit();
- for (LinkMan linkMan : linkMans) {
- System.out.println(linkMan);
- }
- }
- /**
- * 分頁查詢
- * MySQL中分頁關鍵字:
- * Limit
- * limit的兩個引數: 第一個引數:查詢的開始記錄索引。(它是從0開始的)
- * 第二個引數:每次查詢多少條記錄。(它是固定的)
- * Hibernate中涉及的方法
- * setFirstResult(int firstResult):查詢的開始記錄索引
- * setMaxResults(int maxResults):每次查詢多少條記錄
- */
- @Test
- public void test5(){
- Session session = HibernateUtils.getCurrentSession();
- Transaction transaction = session.beginTransaction();
- //1.獲取Query物件
- Query query = session.createQuery("from LinkMan");
- //2.使用Hibernate提供的方法來設定分頁條件
- Integer firstResult = 0;
- Integer maxResults = 2;
- query.setFirstResult(firstResult);
- query.setMaxResults(maxResults);
- //3.執行query物件的方法
- @SuppressWarnings("unchecked")
- List<LinkMan> list = query.list();
- transaction.commit();
- for (LinkMan linkMan : list) {
- System.out.println(linkMan);
- }
- }
- /**
- * 統計查詢
- * 其實就是在HQL語句中使用聚合函式
- * count() sum() avg() max() min()
- * 使用聚合函式查詢時,如果沒有group by,返回的結果集是一行一列的
- *
- * 聚合函式都不會計算為null的欄位。
- *
- * count(*)和count(主鍵)是一樣的。
- */
- @Test
- public void test6(){
- Session session = HibernateUtils.getCurrentSession();
- Transaction transaction = session.beginTransaction();
- // 查詢一共有多少個聯絡人
- Query query = session.createQuery("select count(lkmId) from LinkMan");
- Long count = (Long) query.uniqueResult();
- transaction.commit();
- System.out.println(count);
- }
- /**
- * 投影查詢:
- * 當我們查詢實體物件時,並不需要所有欄位資訊,只查詢部分,但是還想讓他成為一個實體物件。其實就是用部分欄位來投影出整個實體物件。
- * 使用要求:
- * HQL語句:
- * 寫法必須是 new 實體類名稱(查詢的欄位)
- * select new Customer(custId,custName) from Customer
- * 注意:如果你的實體類在工程中唯一,則可以直接寫類名。如果實體類在工程中不唯一,需要寫全限定類名。
- * 實體類要求:
- * 必須在實體類中提供一個相同引數列表的建構函式。
- *
- */
- @Test
- public void test71(){
- Session session = HibernateUtils.getCurrentSession();
- Transaction transaction = session.beginTransaction();
- // 只獲取客戶的ID和名字,並封裝成客戶物件
- Query query = session.createQuery("select new Customer(custId, custName) from Customer");
- @SuppressWarnings("unchecked")
- List<Customer> customers = query.list();
- transaction.commit();
- for (Customer customer : customers) {
- System.out.println(customer.getCustId() + " " + customer.getCustName());
- }
- }
- @Test
- public void test72(){
- Session s = HibernateUtils.getCurrentSession();
- Transaction tx = s.beginTransaction();
- //1.獲取Query物件
- Query query = s.createQuery("select custId,custName from Customer ");
- //2.執行query物件的方法
- @SuppressWarnings("unchecked")
- List<Object[]> list = query.list();
- tx.commit();
- for(Object[] os : list){
- System.out.println("----------每個陣列中的內容------------");
- for(Object o : os){
- System.out.println(o);
- }
- }
- }
- /**
- * 左外連線查詢和迫切左外連線查詢的區別
- * 區別:
- * 返回的結果集不一樣。在實際開發中用的不多,此處講解就是為了說明他們之間的區別
- * 注意:
- * Hibernate中沒有右外連線
- *
- * Hibernate左外連線返回的資料:
- * 返回的是一個有Object陣列組成的List集合,該陣列中有兩個物件。一個是主表實體,一個是從表實體。
- * 主表實體有可能重複
- */
- //左外連線查詢
- @Test
- public void test81(){
- Session session = HibernateUtils.getCurrentSession();
- Transaction transaction = session.beginTransaction();
- //1.獲取Query物件
- //sql語句的左外:select * from cst_customer c left outer join cst_linkman l on c.cust_id = l.lkm_cust_id;
- Query query = session.createQuery("from Customer c left join c.linkMans");
- //2.執行query物件的方法
- @SuppressWarnings("unchecked")
- List<Object[]> list = query.list();
- transaction.commit();
- for (Object[] objects : list) {
- System.out.println("------一組物件-------");
- for (Object object : objects) {
- System.out.println(object);
- }
- }
- }
- /**
- * 迫切左外連線查詢:
- * 要想使用迫切,需要在查詢HQL語句中加入一個關鍵字:fetch
- * Hibernate迫切左外連線返回的資料:
- * 返回的是左表實體物件的List集合,並且左表中對應右表的欄位已經被填充
- */
- @Test
- public void test82(){
- Session session = HibernateUtils.getCurrentSession();
- Transaction transaction = session.beginTransaction();
- //1.獲取Query物件
- Query query = session.createQuery("from Customer c left join fetch c.linkMans");
- //2.執行query物件的方法
- @SuppressWarnings("unchecked")
- List<Customer> customers = query.list();
- transaction.commit();
- for (Customer customer : customers) {
- System.out.println("------一組物件-------");
- System.out.println(customer);
- for (LinkMan linkMan : customer.getLinkMans()) {
- System.out.println(linkMan);
- }
- System.out.println("");
- }
- }
- /**
- * 使用HQL進行更新操作
- */
- @Test
- public void test9(){
- Session session = HibernateUtils.getCurrentSession();
- Transaction transaction = session.beginTransaction();
- //1.獲取Query物件
- Query query = session.createQuery("update Customer set custName = ? where custId = ?");
- query.setString(0, "XX公司");
- query.setString(1, "1");
- //2.執行query物件的方法
- int result = query.executeUpdate();
- transaction.commit();
- System.out.println(result);
- }
- }
QBC查詢
QBC(Query By Criteria)是Hibernate提供的另一種檢索物件的方式,它主要由Criteria 介面、Criterion介面和Expression類組成 。Criteria介面是Hibernate API中的一個查詢介面,它需要由session進行建立。Criterion是Criteria的查詢條件,在Criteria中提供了add(Criterion criterion)方法來新增查詢條件。
涉及的物件:
Criteria
DetachedCriteria
獲取的方式:
session.createCriteria(Class clazz);引數指的是要查詢的位元組碼
新增條件的方法:
Criteria的add方法
新增條件涉及的物件:
Restrictions
Restrictions類提供的方法
方法名 | 說明 |
Restrictions.eq | 等於 |
Restrictions. allEq | 使用 Map ,使用key/value進行多個等於的比較 |
Restrictions.gt | 大於> |
Restrictions.ge | 大於等於>= |
Restrictions.lt | 小於 |
Restrictions.le | 小於等於<= |
Restrictions.between | 對應 SQL 的 between 子句 |
Restrictions.like | 對應 SQL 的 like 子句 |
Restrictions.in | 對應 SQL 的 IN 子句 |
Restrictions.and | and 關係 |
Restrictions.or | or 關係 |
Restrictions.sqlRestriction | SQL 限定查詢 |
離線條件檢索
DetachedCriteria 翻譯為離線條件查詢,因為它是可以脫離Session來使用的一種條件查詢物件,我們都知道Criteria物件必須由Session物件來建立。那麼也就是說必須先有Session才可以生成Criteria物件。而DetachedCriteria物件可以在其他層對條件進行封裝。
這個物件也是比較有用的,尤其在SSH整合以後這個物件經常會使用 。它的主要優點是做一些特別複雜的條件查詢的時候,往往會在WEB層向業務層傳遞很多的引數,業務層又會將這些引數傳遞給DAO層。最後在DAO中拼接SQL完成查詢。有了離線條件查詢物件後,那麼這些工作都可以不用關心了,我們可以在WEB層將資料封裝好,傳遞到業務層,再由業務層傳遞給DAO完成查詢。
測試QBC檢索方式
- package com.pc.hibernate.test.querymethod;
- import java.util.List;
- import org.hibernate.Criteria;
- import org.hibernate.Session;
- import org.hibernate.Transaction;
- import org.hibernate.criterion.DetachedCriteria;
- import org.hibernate.criterion.Order;
- import org.hibernate.criterion.Projections;
- import org.hibernate.criterion.Restrictions;
- import org.junit.Test;
- import com.pc.hibernate.domain.Customer;
- import com.pc.hibernate.domain.LinkMan;
- import com.pc.hibernate.utils.HibernateUtils;
- /**
- * Hibernate中的查詢方式:
- * QBC查詢:
- * Query By Criteria 它是一種更加物件導向的查詢方式。
- * 它把查詢條件都用方法封裝了。裡面的引數全都需要使用實體類的屬性名稱。
- * 涉及的物件:
- * Criteria
- * DetachedCriteria
- * 獲取的方式:
- * session.createCriteria(Class clazz);引數指的是要查詢的位元組碼
- * 新增條件的方法:
- * Criteria的add方法。
- * 新增條件涉及的物件:
- * Restrictions
- *
- * @author Switch
- */
- public class TestQBCQuery {
- /**
- * 基本查詢:查詢所有
- *
- * 需求:
- * 查詢所有客戶
- */
- @Test
- public void test1(){
- Session session = HibernateUtils.getCurrentSession();
- Transaction tx = session.beginTransaction();
- //1.獲取Criteria物件
- Criteria criteria = session.createCriteria(Customer.class);
- //2.執行list方法,得到結果集
- @SuppressWarnings("unchecked")
- List<Customer> customers = criteria.list();
- tx.commit();
- for (Customer customer : customers) {
- System.out.println(customer);
- }
- }
- /**
- * 條件查詢
- * 需求:查詢客戶級別是23的,客戶名稱帶有集字的
- */
- @Test
- public void test2(){
- Session session = HibernateUtils.getCurrentSession();
- Transaction tx = session.beginTransaction();
- //1.獲取Criteria物件
- Criteria criteria = session.createCriteria(Customer.class);
- // 新增條件
- criteria.add(Restrictions.eq("custLevel", "23"));
- criteria.add(Restrictions.like("custName", "%集%"));
- //2.執行list方法,得到結果集
- @SuppressWarnings("unchecked")
- List<Customer> customers = criteria.list();
- tx.commit();
- for (Customer customer : customers) {
- System.out.println(customer);
- }
- }
- /**
- * 分頁查詢
- *
- * 涉及的方法:
- * setFirstResult(int firstResult);
- * setMaxResults(int maxResults);
- * 含義和HQL是一模一樣的
- */
- @Test
- public void test3(){
- Session session = HibernateUtils.getCurrentSession();
- Transaction tx = session.beginTransaction();
- //1.獲取Criteria物件
- Criteria criteria = session.createCriteria(Customer.class);
- criteria.setFirstResult(0);
- criteria.setMaxResults(2);
- //2.執行list方法,得到結果集
- @SuppressWarnings("unchecked")
- List<Customer> customers = criteria.list();
- tx.commit();
- for (Customer customer : customers) {
- System.out.println(customer);
- }
- }
- /**
- * 統計查詢:
- * 使用QBC來新增聚合函式
- *
- * count() avg() min() max() sum()
- *
- * 涉及的方法:
- * setProjections(Projection p ); 它可以加查詢語句的結構。
- * 涉及的類:
- * Projections
- * 該類中提供了一些靜態方法
- */
- @Test
- public void test4(){
- Session session = HibernateUtils.getCurrentSession();
- Transaction tx = session.beginTransaction();
- //1.獲取Criteria物件
- Criteria criteria = session.createCriteria(Customer.class);
- criteria.setProjection(Projections.count("custId"));
- //2.執行uniqueResult方法,得到結果
- Long result = (Long) criteria.uniqueResult();
- tx.commit();
- System.out.println(result);
- }
- /**
- * 排序查詢
- *
- * 涉及方法:
- * Criteria的addOrder方法。該方法需要一個Order物件作為引數
- * Order物件有兩個方法:
- * desc(String propertyName):按照指定的屬性名稱,倒序排序。
- * asc(String propertyName):按照自頂的屬性名稱,正序排序。
- */
- @Test
- public void test5(){
- Session session = HibernateUtils.getCurrentSession();
- Transaction tx = session.beginTransaction();
- //1.獲取Criteria物件
- Criteria criteria = session.createCriteria(LinkMan.class);
- criteria.addOrder(Order.desc("lkmId"));
- //2.執行list方法,得到結果集
- @SuppressWarnings("unchecked")
- List<LinkMan> linkMans = criteria.list();
- tx.commit();
- for (LinkMan linkMan : linkMans) {
- System.out.println(linkMan);
- }
- }
- /**
- * 離線查詢:
- * 線上物件:
- * Criteria物件。它的獲取必須要一個可用的Session來建立。如果Session不能用,則不能建立Criteria。
- * 我們使用Criteria進行的查詢就是線上查詢。
- * 離線物件:
- * 建立DetachedCriteria不需要一個可用的Session。
- * 用DetachedCriteria進行的查詢就叫做離線查詢
- * 涉及的物件
- * DetachedCriteria
- * 如何獲取
- * DetachedCriteria.forClass(Class clazz);引數的含義:要查詢的實體類
- * 如何設定查詢條件:
- * 和Criteria是一樣的
- *
- * 在實際開發中:多條件查詢用此種方式
- */
- //Servlet的方法
- @Test
- public void doGet(){
- //1.獲取請求引數
- String custLevel = "23";
- String custName = "集";
- //2.查詢所有客戶
- DetachedCriteria dCriteria = DetachedCriteria.forClass(Customer.class);
- dCriteria.add(Restrictions.eq("custLevel", custLevel));
- dCriteria.add(Restrictions.like("custName", "%"+custName+"%"));
- List<Customer> cs = servicefindAllCustomer(dCriteria);
- for(Customer c : cs){
- //3.存入請求域中
- //4.轉向列表頁面
- System.out.println(c);
- }
- }
- //Service的方法
- public List<Customer> servicefindAllCustomer(DetachedCriteria dCriteria){
- return daofindAllCustomer(dCriteria);
- }
- //Dao中的方法
- public List<Customer> daofindAllCustomer(DetachedCriteria dCriteria){
- Session s = HibernateUtils.getCurrentSession();
- Transaction tx = s.beginTransaction();
- //1.把離線物件啟用
- Criteria c = dCriteria.getExecutableCriteria(s);
- //3.執行list方法,得到結果集
- @SuppressWarnings("unchecked")
- List<Customer> list = c.list();
- tx.commit();
- return list;
- }
- }
原生SQL查詢
採用HQL或QBC檢索方式時,Hibernate生成標準的SQL查詢語句,適用於所有的資料庫平臺,因此這兩種檢索方式都是跨平臺的。但有的應用程式可能需要根據底層資料庫的SQL方言,來生成一些特殊的查詢語句。在這種情況下,可以利用Hibemate提供的原生SQL檢索方式 。
原生SQL查詢時通過SQLQuery sqlQuery = session.createSQLQuery(String sql)來實現的,因為操作方式就是SQL語句,故不再介紹。
該博文使用的Hibernate配置檔案和對映檔案
- /**
- * SQLQuery 它使用的是原始的SQL語句查詢
- */
- @Test
- public void test3() {
- Session s = HibernateUtils.getCurrentSession();
- Transaction tx = s.beginTransaction();
- // 1.獲取SQLQuery物件
- SQLQuery sqlquery = s.createSQLQuery("select * from cst_customer");// 引數是SQL語句
- // 2.執行sqlquery的方法,返回結果集
- /*
- * List<Object[]> list = sqlquery.list(); for(Object[] os : list){
- * System.out.println(
- * "-------------每出現一行分割線,表示外層迴圈執行了一次-------------------"); <br/>
- * for(Object o : os){ System.out.println(o); } }
- */
- // 新增實體類位元組碼,把查詢結果轉成實體類物件
- sqlquery.addEntity(Customer.class);
- List<Customer> cs = sqlquery.list();
- for (Customer c : cs) {
- System.out.println(c);
- }
- tx.commit();
- }
該博文使用的Hibernate配置檔案和對映檔案
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">
- <!--
- 1、匯入dtd約束
- 在Hibernate的核心jar包中:hibernate-mapping-3.0.dtd
- 2、編寫配置檔案
- 實體類和資料庫表的對應關係
- 實體類中屬性和表的欄位的對應關係
- -->
- <hibernate-mapping package="com.pc.hibernate.domain">
- <!-- class標籤:
- 作用:用於配置實體類和表之間的對應關係
- 屬性:
- name:實體類的名稱。它應該寫全限定類名
- table:資料庫表的名稱
- -->
- <class name="Customer" table="cst_customer" lazy="true" batch-size="3">
- <!-- id標籤:
- 作用:對映主鍵
- 屬性:
- name:實體類的屬性名稱
- column:資料庫表的欄位名稱
- type:主鍵的型別
- -->
- <id name="custId" column="cust_id" type="java.lang.Long">
- <!-- generator標籤:
- 作用:主鍵的生成方式
- 屬性:
- class:指定方式
- 取值:native
- 含義:使用本地資料庫的自動增長能力。
- -->
- <generator class="native"/>
- </id>
- <!-- property標籤:
- 作用:對映其他欄位
- 屬性:
- name:實體類的屬性名稱
- column:資料庫表的欄位名稱
- type:欄位的型別
- length:資料庫中對應列的長度
- -->
- <property name="custName" column="cust_name" type="java.lang.String" length="32"/>
- <property name="custSource" column="cust_source" type="java.lang.String" length="32"/>
- <property name="custIndustry" column="cust_industry" type="java.lang.String" length="32"/>
- <property name="custLevel" column="cust_level" type="java.lang.String" length="32"/>
- <property name="custAddress" column="cust_address" type="java.lang.String" length="128"/>
- <property name="custPhone" column="cust_phone" type="java.lang.String" length="64"/>
- <!-- 配置一對多 -->
- <set name="linkMans" inverse="false" cascade="save-update" batch-size="4" lazy="true" fetch="select">
- <key column="lkm_cust_id" />
- <one-to-many class="LinkMan"/>
- </set>
- </class>
- </hibernate-mapping>
LinkMan.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 package="com.pc.hibernate.domain">
- <class name="LinkMan" table="cst_linkman">
- <id name="lkmId" column="lkm_id" type="java.lang.Long">
- <generator class="native" />
- </id>
- <property name="lkmName" column="lkm_name" type="java.lang.String" length="16"/>
- <property name="lkmGender" column="lkm_gender" type="java.lang.String" length="10"/>
- <property name="lkmPhone" column="lkm_phone" type="java.lang.String" length="16"/>
- <property name="lkmMobile" column="lkm_mobile" type="java.lang.String" length="16"/>
- <property name="lkmEmail" column="lkm_email" type="java.lang.String" length="64"/>
- <property name="lkmPosition" column="lkm_position" type="java.lang.String" length="16"/>
- <property name="lkmMemo" column="lkm_memo" type="java.lang.String" length="512"/>
- <!-- 配置多對一 -->
- <many-to-one name="customer" class="Customer" column="lkm_cust_id" cascade="save-update" lazy="proxy" fetch="select"/>
- </class>
- </hibernate-mapping>
hibernate.cfg.xml
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE hibernate-configuration PUBLIC
- "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
- "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
- <!-- 1、匯入dtd約束 在hibernate核心jar包中:hibernate-configuration-3.0.dtd 2、編寫配置檔案 -->
- <hibernate-configuration>
- <!-- 配置SessionFactory -->
- <!-- 建立SessionFactory需要3部分資訊。 而配置檔案中要寫哪些配置,我們可以翻閱資料。 -->
- <!-- 第一部分:連線資料庫的基本資訊,第二部分:hibernate的基本配置,第三部分:對映檔案的位置 -->
- <session-factory>
- <!-- 1、連線資料庫的基本資訊 -->
- <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
- <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/mycrm</property>
- <property name="hibernate.connection.username">root</property>
- <property name="hibernate.connection.password">123456</property>
- <!-- 資料庫的方言 -->
- <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
- <!-- 2、hibernate的基本配置 -->
- <!-- 是否顯示SQL語句 -->
- <property name="hibernate.show_sql">true</property>
- <!-- 是否格式化顯示SQL語句 -->
- <!-- <property name="hibernate.format_sql">true</property> -->
- <!-- 採用何種策略來建立表結構: -->
- <!-- update:檢查表結構和實體類對映檔案的變化,如果發現對映檔案和表結構不一致,更新表結構。 -->
- <!-- 注意:hibernate不能建立資料庫,只能在有資料庫的情況下建立表結構。 -->
- <property name="hibernate.hbm2ddl.auto">update</property>
- <!-- 配置hibernate使用連線池:告知Hibernate使用連線池的廠商 -->
- <property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
- <!-- 配置把Session繫結到當前執行緒上,從而保證一個執行緒只有一個Session -->
- <property name="hibernate.current_session_context_class">thread</property>
- <!-- 3、對映檔案的位置 -->
- <mapping resource="com/pc/hibernate/domain/Customer.hbm.xml" />
- <mapping resource="com/pc/hibernate/domain/LinkMan.hbm.xml" />
- </session-factory>
- </hibernate-configuration>
相關文章
- Hibernate 框架的查詢方式框架
- hibernate(七) hibernate中查詢方式詳解
- hibernate的三種查詢方式
- hibernate查詢的方式 都有哪些
- Hibernate的查詢方式與策略
- Hibernate 查詢
- SSH_hibernate---六種查詢資料庫方式資料庫
- Hibernate——Query查詢
- hibernate中hql查詢
- Hibernate hql 多表查詢
- Hibernate 查詢語句
- Hibernate查詢自動更新
- Hibernate連線查詢join
- hibernate 動態查詢(DetachedCriteria )
- hibernate批量查詢問題
- Hibernate通常是三種:hql查詢,QBC查詢和QBE查詢:
- hibernate的native sql查詢SQL
- Hibernate的Criteria查詢問題。
- hibernate的查詢快取薦快取
- Hibernate【查詢、連線池、逆向工程】
- Hibernate 之強大的HQL查詢
- Hibernate分頁查詢原理解讀
- 關於Hibernate的查詢問題
- Hibernate綜合查詢解決方案 (轉)
- Hibernate-ORM:13.Hibernate中的連線查詢ORM
- hibernate異常之--count查詢異常
- hibernate的hql查詢語句總結
- Hibernate對於複雜查詢好用嗎?
- Hibernate 分頁查詢的一點疑惑
- hibernate跟jdbc的查詢速度相差10???JDBC
- Hibernate實現分頁查詢的原理
- hibernate複合主鍵查詢問題
- 【Hibernate框架開發之八】Hibernate 查詢語言Query Language(HQL)框架
- 391、Java框架46 -【Hibernate - 查詢HQL、查詢Criteria、查詢標準SQL】 2020.10.19Java框架SQL
- 如何使用Hibernate/JPA的JPQL/HQL查詢提取?
- hibernate查詢結果Logic:iterate問題
- hibernate查詢的問題,請高手賜教!
- [破解]為什麼hibernate插入快,查詢慢