天天看點

ssh備考-03hibernate各種查詢方式

​​01搭建hibernate架構​​

​​02多表關聯關系映射​​

03hibernate各種查詢方式

目錄

​​一、通過主鍵查詢&對象導航方式​​

​​Demo1to2.java​​

​​二、HQL的檢索方式 ★(用得最多) (除條件查詢專用三外)​​

​​Demo3.java​​

​​三、QBC的檢索方式 ★ (條件查詢專用   也隻會用在條件查詢 )​​

​​Demo4.java​​

​​四、HQL多表查詢​​

資料下載下傳位址: ​​直接下載下傳hibernate02_1.zip​​​       ​​網盤備份下載下傳​​

本篇就是在上篇項目的基礎進行的測試查詢

ssh備考-03hibernate各種查詢方式

1. 唯一辨別OID的檢索方式 (就是通過主鍵來查詢  簡單)

    * session.get(對象.class,OID) 

    * session.load(對象.class,OID) 延遲加載

2. 對象的導航的方式  new User().getRole().getRname()   (簡單  原理其實是el表達式的寫法${user.customer.linkman})

    *Customer.getLinkmans() 查詢Customer下所有客戶的對象導航方式

**Hibernate架構推薦使用3、4兩種方式查詢**

3. HQL的檢索方式

    * Hibernate Query Language    -- Hibernate的查詢語言

4. QBC的檢索方式

    * Query By Criteria    -- 條件查詢

5. SQL檢索方式(了解)

    * 本地的SQL檢索

一、通過主鍵查詢&對象導航方式

Demo1to2.java

package cn.ahpu.testQuery;

import java.util.Set;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import cn.ahpu.domain.Customer;
import cn.ahpu.domain.Linkman;
import cn.ahpu.utils.HibernateUtils;

/**
 * 對象導航方式查詢
 * @author 軟體163韓竹安
 * 2019年12月23日-下午7:25:11
 */
public class Demo1to2 {
  /**
   * 導入資料
   */
  @Test
  public void data(){
    Session session = HibernateUtils.getCurrentSession();
    Transaction tr = session.beginTransaction();
    //準備資料
    Customer c1 = new Customer("張三", "110");
    Customer c2 = new Customer("李四", "120");
    Customer c3 = new Customer("王五", "119");
    Customer c4 = new Customer("趙六", "114");
    Linkman l1=new Linkman("張媽", "110");
    Linkman l2=new Linkman("張爸", "110");
    Linkman l3=new Linkman("張爺", "110");
    Linkman l4=new Linkman("李爸", "120");
    Linkman l5=new Linkman("李媽", "120");
    Linkman l6=new Linkman("王爸", "119");
    Linkman l7=new Linkman("王媽", "119");
    Linkman l8=new Linkman("趙志成", "114");
    //單向關聯
    c1.getLinkmans().add(l1);
    c1.getLinkmans().add(l2);
    c1.getLinkmans().add(l3);
    c2.getLinkmans().add(l4);
    c2.getLinkmans().add(l5);
    c3.getLinkmans().add(l6);
    c3.getLinkmans().add(l7);
    c4.getLinkmans().add(l8);
    //級聯儲存
    session.save(c1);
    session.save(c2);
    session.save(c3);
    session.save(c4);
    
    tr.commit();
  }
  
  /**
   * 對象導航方式
   * 
   * 通過客戶直接拿聯系人
   */
  @Test
  public void test1(){
    Session session = HibernateUtils.getCurrentSession();
    Transaction tr = session.beginTransaction();
    Customer c = session.get(Customer.class, 1L);//查到了customer後
    System.out.println("============================");
    Set<Linkman> linkmans = c.getLinkmans();//其下有哪些聯系人不用查了,直接拿即可,自動發送sql語句幫你查               才開始發送sql語句   
    for (Linkman l : linkmans) {
      System.out.println(l);
    }
    tr.commit();
  }
  
  /**
   * 對象導航方式
   * 
   * 通過聯系人直接拿客戶
   */
  @Test
  public void test2(){
    Session session = HibernateUtils.getCurrentSession();
    Transaction tr = session.beginTransaction();
    Linkman l = session.get(Linkman.class, 1L);
    System.out.println(l.getCustomer());//所屬客戶不用查了,直接拿
    tr.commit();
  }
}      

因為簡單,是以用得很多

二、HQL的檢索方式 ★(用得最多) (除條件查詢專用三外)

1. HQL的介紹

        HQL(Hibernate Query Language) 是面向對象的查詢語言, 它和 SQL 查詢語言有些相似

        在 Hibernate 提供的各種檢索方式中, HQL 是使用最廣的一種檢索方式

2. HQL與SQL的關系

    * HQL 查詢語句是面向對象的,Hibernate負責解析HQL查詢語句, 然後根據對象-關系映射檔案中的映射資訊, 把 HQL 查詢語句翻譯成相應的 SQL 語句. 

    * HQL 查詢語句中的主體是域模型中的類及類的屬性  即操作面向javabean的查詢語句

    * SQL 查詢語句是與關系資料庫綁定在一起的. SQL查詢語句中的主體是資料庫表及表的字段  即面向資料庫表的查詢語句

1. HQL基本的查詢格式

    * 支援方法鍊的程式設計,即直接調用list()方法

    * 簡單的代碼如下

        * session.createQuery("from Customer").list();

2. 使用别名的方式

    * 可以使用别名的方式

        * session.createQuery("from Customer c").list();

        * session.createQuery("select c from Customer c").list();

3. 排序查詢

    * 排序查詢和SQL語句中的排序的文法是一樣的

        * 升序

            * session.createQuery("from Customer order by cust_id").list();

        * 降序

            * session.createQuery("from Customer order by cust_id desc").list();

4. 分頁查詢

    * Hibernate架構提供了分頁的方法,咱們可以調用方法來完成分頁 limit 查詢起始處,每頁幾條  (目前頁-1)*pagesize《==》頁起始頁碼

    * 兩個方法如下

        * setFirstResult(a)        -- 從哪條記錄開始,如果查詢是從第一條開啟,值是0

        * setMaxResults(b)        -- 每頁查詢的記錄條數

    * 示範代碼如下

        * List<LinkMan> list = session.createQuery("from LinkMan").setFirstResult(0).setMaxResults().list();

5. 帶條件的查詢   (了解  條件查詢是QBC的專利)

    * setParameter("?号的位置,預設從0開始","參數的值"); 不用考慮參數的具體類型

    * 按位置綁定參數的條件查詢(指定下标值,預設從0開始)

    * 按名稱綁定參數的條件查詢(HQL語句中的 ? 号換成 :名稱 的方式)

    * 例如代碼如下

        Query query = session.createQuery("from Linkman where lkm_name like ? order by lkm_id desc");

        query.setFirstResult(0).setMaxResults(3);

        query.setParameter(0, "%熊%");

        List<Linkman> list = query.list();

        for (Linkman linkman : list) {

            System.out.println(linkman);

        }

投影查詢,可以全查詢然後少輸出點不就行了

1. 投影查詢就是想查詢某一字段的值或者某幾個字段的值   select custName,custPhone from Customer;

2. 投影查詢的案例

    * 如果查詢多個字段,例如下面這種方式

        List<Object[]> list = session.createQuery("select c.cust_name,c.cust_level from Customer c").list();

        for (Object[] objects : list) {

            System.out.println(Arrays.toString(objects));

        }

    * 如果查詢兩個字段,也可以把這兩個字段封裝到對象中

        * 先在持久化類中提供對應字段的構造方法

        * 使用下面這種HQL語句的方式

            List<Customer> list = session.createQuery("select new Customer(c.cust_name,c.cust_level) from Customer c").list();

            for (Customer customer : list) {

                System.out.println(customer);

            }

聚合函數查詢的api

1. 擷取總的記錄數

    Session session = HibernateUtils.getCurrentSession();

    Transaction tr = session.beginTransaction();

    List<Number> list = session.createQuery("select count(c) from Customer c").list();

    Long count = list.get(0).longValue();

    System.out.println(count);

    tr.commit();

2. 擷取某一列資料的和

    Session session = HibernateUtils.getCurrentSession();

    Transaction tr = session.beginTransaction();

    List<Number> list = session.createQuery("select sum(c.cust_id) from Customer c").list();

    Long count = list.get(0).longValue();

    System.out.println(count);

    tr.commit();

Demo3.java

package cn.ahpu.testQuery;

import java.util.List;
import java.util.Set;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import cn.ahpu.domain.Customer;
import cn.ahpu.domain.Linkman;
import cn.ahpu.utils.HibernateUtils;

/**
 * HQL查詢方式
 * @author 軟體163韓竹安
 * 2019年12月23日-下午7:25:11
 */
public class Demo3 {
  
  /**
   * 基本查詢
   * 查詢所有
   */
  @Test
  public void test1(){
    Session session = HibernateUtils.getCurrentSession();
    Transaction tr = session.beginTransaction();
    Query query = session.createQuery("from Customer");
    List<Customer> customers = query.list();//也可直接session.createQuery("from Customer").list
    for (Customer c : customers) {
      System.out.println(c);
    }
    tr.commit();
  }
  
  /**
   * 排序查詢
   */
  @Test
  public void test2(){
    Session session = HibernateUtils.getCurrentSession();
    Transaction tr = session.beginTransaction();
    //升序
    Query query = session.createQuery("from Customer order by custId");
    List<Customer> customers = query.list();
    for (Customer c : customers) {
      System.out.println(c);
    }
    
    System.out.println("==========================");
    //降序
    query = session.createQuery("from Customer order by custId desc");
    customers = query.list();
    for (Customer c : customers) {
      System.out.println(c);
    }
    tr.commit();
  }
  
  /**
   * 分頁查詢
   * 
   * setFirstResult(a)  起始頁碼a(=(目前頁-1)*pagesize)
     * setMaxResults(b)   每頁記錄條數b
   */
  @Test
  public void test3(){
    Session session = HibernateUtils.getCurrentSession();
    Transaction tr = session.beginTransaction();
    Query query = session.createQuery("from Linkman");
    int page=3;  //目前頁  重1開始
    int b=2;//每頁記錄條數 一般定死
    query.setFirstResult((page-1)*b);
    query.setMaxResults(b);
    List<Linkman> list = query.list();
    System.out.println("每頁"+b+"條,則第"+page+"頁内容如下");
    for (Linkman l : list) {
      System.out.println(l);      
    }
    tr.commit();
  }
  
  /*****************************************聚合查詢*****************************************/
  /**
   * 聚合函數: count() sum() avg() max() min()
   */
  //count()
  @Test
  public void test4(){
    Session session = HibernateUtils.getCurrentSession();
    Transaction tr = session.beginTransaction();
    //查詢所有聯系人的數量   //Number是Long Integer的父類  //傳回的是數量
    List<Number> list = session.createQuery("select count(*) from Linkman").list();
    Long count = list.get(0).longValue();
    System.out.println("聯系人總數:"+count);
    //System.out.println("聯系人總數:"+list.get(0));//直接這麼寫即可
    tr.commit();
  }
  
  //sum()
  @Test
  public void test5(){
    Session session = HibernateUtils.getCurrentSession();
    Transaction tr = session.beginTransaction();
    //所有人的id值之和
    List<Number> list = session.createQuery("select sum(lkmId) from Linkman").list();
    Long count = list.get(0).longValue();
    System.out.println("聯系人id值之和:"+count);
    //System.out.println("聯系人總數:"+list.get(0));//直接這麼寫即可
    tr.commit();
  }
  
}      

三、QBC的檢索方式 ★ (條件查詢專用   也隻會用在條件查詢 )

所有查詢都列出來,但隻練習QBC條件查詢

0. QBC:Query By Criteria  按條件進行查詢

1. 簡單查詢,使用的是Criteria接口

    List<Customer> list = session.createCriteria(Customer.class).list();

    for (Customer customer : list) {

        System.out.println(customer);

    }

2. 排序查詢

    * 需要使用addOrder()的方法來設定參數,參數使用org.hibernate.criterion.Order對象

    * 具體代碼如下:

        Session session = HibernateUtils.getCurrentSession();

        Transaction tr = session.beginTransaction();

        Criteria criteria = session.createCriteria(Linkman.class);

        // 設定排序

        criteria.addOrder(Order.desc("lkm_id"));

        List<Linkman> list = criteria.list();

        for (Linkman linkman : list) {

            System.out.println(linkman);

        }

        tr.commit();

3. 分頁查詢

    * QBC的分頁查詢也是使用兩個方法

        * setFirstResult();

        * setMaxResults();

    * 代碼如下;

        Session session = HibernateUtils.getCurrentSession();

        Transaction tr = session.beginTransaction();

        Criteria criteria = session.createCriteria(Linkman.class);

        // 設定排序

        criteria.addOrder(Order.desc("lkm_id"));

        criteria.setFirstResult(0);

        criteria.setMaxResults(3);

        List<Linkman> list = criteria.list();

        for (Linkman linkman : list) {

            System.out.println(linkman);

        }

        tr.commit();

4. 條件查詢(Criterion是查詢條件的接口,Restrictions類是Hibernate架構提供的工具類,使用該工具類來設定查詢條件)

    * 條件查詢使用Criteria接口的add方法,用來傳入條件。

    * 使用Restrictions的添加條件的方法,來添加條件,例如:

        * Restrictions.eq            -- 相等

        * Restrictions.gt            -- 大于号

        * Restrictions.ge            -- 大于等于

        * Restrictions.lt            -- 小于

        * Restrictions.le            -- 小于等于

        * Restrictions.between        -- 在之間

        * Restrictions.like            -- 模糊查詢

        * Restrictions.in            -- 範圍

        * Restrictions.and            -- 并且

        * Restrictions.or            -- 或者

    * 測試代碼如下

        Session session = HibernateUtils.getCurrentSession();

        Transaction tr = session.beginTransaction();

        Criteria criteria = session.createCriteria(Linkman.class);

        // 設定排序

        criteria.addOrder(Order.desc("lkm_id"));

        // 設定查詢條件

        criteria.add(Restrictions.or(Restrictions.eq("lkm_gender", "男"), Restrictions.gt("lkm_id", 3L)));

        List<Linkman> list = criteria.list();

        for (Linkman linkman : list) {

            System.out.println(linkman);

        }

        tr.commit();

5. 聚合函數查詢(Projection的聚合函數的接口,而Projections是Hibernate提供的工具類,使用該工具類設定聚合函數查詢)

    * 使用QBC的聚合函數查詢,需要使用criteria.setProjection()方法

    * 具體的代碼如下

        Session session = HibernateUtils.getCurrentSession();

        Transaction tr = session.beginTransaction();

        Criteria criteria = session.createCriteria(Linkman.class);

        criteria.setProjection(Projections.rowCount());

        List<Number> list = criteria.list();

        Long count = list.get(0).longValue();

        System.out.println(count);

        tr.commit();

    *前面條件查詢是criteria.add(Restrictions.條件) 此處聚合函數是criteria.setProjection(Projections.聚合函數)

    *注意:Projections.聚合函數   Projections下幾乎封裝了所有的集合函數 比如:

        Projections.max,Projections.count,Projections.avg等等

    *此處是criteria.list  模闆就是getHibernateTemplate().findByCriteria(criteria);

1. 離線條件查詢使用的是DetachedCriteria接口進行查詢,離線條件查詢對象在建立的時候,不需要使用Session對象,隻是在查詢的時候使用Session對象即可。

2. 建立離線條件查詢對象

    * DetachedCriteria criteria = DetachedCriteria.forClass(Linkman.class);

3. 具體的代碼如下

    Session session = HibernateUtils.getCurrentSession();

    Transaction tr = session.beginTransaction();

    DetachedCriteria criteria = DetachedCriteria.forClass(Linkman.class);

    // 設定查詢條件

    criteria.add(Restrictions.eq("lkm_gender", "男"));

    // 查詢資料

    List<Linkman> list = criteria.getExecutableCriteria(session).list();

    for (Linkman linkman : list) {

        System.out.println(linkman);

    }

    tr.commit();

Demo4.java

package cn.ahpu.testQuery;

import java.util.ArrayList;
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.Restrictions;
import org.junit.Test;

import cn.ahpu.domain.Customer;
import cn.ahpu.domain.Linkman;
import cn.ahpu.utils.HibernateUtils;

/**
 * 測試QBC的檢索方式 
 * @author 軟體163韓竹安
 * 2019年12月23日-下午10:49:24
 */
public class Demo4 {
  /*********************簡單示範普通查詢*********************/
  //查詢所有
  @Test
  public void test1(){
    Session session = HibernateUtils.getCurrentSession();
    Transaction tr = session.beginTransaction();
    List<Customer> list = session.createCriteria(Customer.class).list();
    for (Customer c : list) {
      System.out.println(c);
    }
    tr.commit();
  }
  
  //排序查詢
  @Test
  public void test2(){
    Session session = HibernateUtils.getCurrentSession();
    Transaction tr = session.beginTransaction();
    Criteria criteria = session.createCriteria(Customer.class);
    criteria.addOrder(Order.desc("custId"));//qbc各種查詢方式看起來都像是條件查詢  都是加條件的形式
    List<Customer> list = criteria.list();
    for (Customer c : list) {
      System.out.println(c);
    }
    tr.commit();
  }
  
  //分頁查詢和HQL差不多
  @Test
  public void test3(){
    Session session = HibernateUtils.getCurrentSession();
    Transaction tr = session.beginTransaction();
    Criteria criteria = session.createCriteria(Customer.class);
    criteria.addOrder(Order.desc("custId"));//qbc各種查詢方式看起來都像是條件查詢  都是加條件的形式
    //加兩個條件就變成了條件查詢
    criteria.setFirstResult((2-1)*2);
    criteria.setMaxResults(2);//每頁兩個查詢 查詢第二頁
    List<Customer> list = criteria.list();
    for (Customer c : list) {
      System.out.println(c);
    }
    tr.commit();
  }
  
  /**********************************重頭戲,條件查詢**********************************/
  @Test
  public void test4(){
    Session session = HibernateUtils.getCurrentSession();
    Transaction tr = session.beginTransaction();
    Criteria criteria = session.createCriteria(Linkman.class);
    
    //添加條件   where lkmName like "李%" or lkmPhone = '114'
    criteria.add(Restrictions.or(Restrictions.eq("lkmPhone", "114"),
           Restrictions.like("lkmName", "李%")));//add(Restrictions()嵌套形式)  添加條件
    
    //between查詢 (兩次測試并一次寫的)
    /*criteria.add(Restrictions.between("lkmId",2L,5L));*/
    
    List<Linkman> list = criteria.list();
    for (Linkman l : list) {
      System.out.println(l);
    }
    tr.commit();
  }
  
  
  /**
   * in查詢
   */
  @Test
  public void test5(){
    Session session = HibernateUtils.getCurrentSession();
    Transaction tr = session.beginTransaction();
    Criteria criteria = session.createCriteria(Linkman.class);
    
    /*List<Long> params=new ArrayList<Long>();
    params.add(1L);
    params.add(3L);
    params.add(5L);
    params.add(7L);
    criteria.add(Restrictions.in("lkmId", params));*/
    
    //看api提示可知也可用此一句
    criteria.add(Restrictions.in("lkmId", new Object[]{1L,3L,5L,7L}));
    
    
    List<Linkman> list = criteria.list();
    for (Linkman l : list) {
      System.out.println(l);
    }
    tr.commit();
  }
  
  /**
   * 是否為空
   */
  @Test
  public void test6(){
    Session session = HibernateUtils.getCurrentSession();
    Transaction tr = session.beginTransaction();
    Criteria criteria = session.createCriteria(Linkman.class);
    
    //查找所有lkmPhone為空的聯系人記錄   (測試前故意到資料中删除兩個字段的lkmPhone)
    //criteria.add(Restrictions.isNull("lkmPhone"));//String類型的""不是null
    criteria.add(Restrictions.isNull("customer"));
    
    List<Linkman> list = criteria.list();
    for (Linkman l : list) {
      System.out.println(l);
    }
    tr.commit();
  }
  
  /**
   * 示範離線條件對象
   * 仔細分析下面代碼 大體上和前面的查詢差不多
   * 離線查詢的好處,不需要session就可以建立查詢接口,就可以設定查詢參數了
   * 唯一需要session的時候就是執行的時候擷取一下
   */
  @Test
  public void run10(){
    Session session = HibernateUtils.getCurrentSession();
    Transaction tr = session.beginTransaction();
    
    //建立離線條件的查詢對象
    DetachedCriteria dcriteria = DetachedCriteria.forClass(Linkman.class);
    //添加查詢的條件了
    dcriteria.add(Restrictions.eq("lkmPhone", "110"));
    //開始查詢了  查詢的時候仍然需要session  那麼就要自己擷取session了   好處真正查詢時才需要session 之前都不要
    List<Linkman> list = dcriteria.getExecutableCriteria(session).list();
    for (Linkman linkman : list) {
      System.out.println(linkman);      
    }
    
    tr.commit();
  }

  @Test
  public void test7(){
    Session session = HibernateUtils.getCurrentSession();
    Transaction tr = session.beginTransaction();
    DetachedCriteria dcriteria = DetachedCriteria.forClass(Linkman.class);
    dcriteria.add(Restrictions.like("lkmName", "李%"));
    List<Linkman> list = dcriteria.getExecutableCriteria(session).list();//最終查詢時才要下session
    for (Linkman man : list) {
      System.out.println(man);
    }
    tr.commit();
  }

}      

四、SQL檢索方式 (都用hibernate架構了,就不要sql語句了 不了解了)

未完待續.......

四、HQL多表查詢(多表查詢HQL最友善 單獨拿出來)

多表查詢用HQL最簡單
1. 多表的查詢進來使用HQL語句進行查詢,HQL語句和SQL語句的查詢文法比較類似。
  * 内連接配接查詢
    * 顯示内連接配接
      * select * from customers c inner join orders o on c.cid = o.cno;
    * 隐式内連接配接
      * select * from customers c,orders o where c.cid = o.cno;
  
  * 外連接配接查詢
    * 左外連接配接
      * select * from customers c left join orders o on c.cid = o.cno;
    * 右外連接配接
      * select * from customers c right join orders o on c.cid = o.cno;

2. HQL的多表查詢
  * 迫切和非迫切:
    * 非迫切傳回結果是Object[]
    * 迫切連接配接傳回的結果是對象,把客戶的資訊封裝到客戶的對象中,把訂單的資訊封裝到客戶的Set集合中。

3. 内連接配接查詢
  * 内連接配接使用 inner join ,預設傳回的是Object數組
    Session session = HibernateUtils.getCurrentSession();
    Transaction tr = session.beginTransaction();
    List<Object[]> list = session.createQuery("from Customer c inner join c.linkmans").list();
    for (Object[] objects : list) {
      System.out.println(Arrays.toString(objects));
    }
    tr.commit();
  
  * 迫切内連接配接:inner join fetch ,傳回的是實體對象
    Session session = HibernateUtils.getCurrentSession();
    Transaction tr = session.beginTransaction();
    List<Customer> list = session.createQuery("from Customer c inner join fetch c.linkmans").list();
    Set<Customer> set = new HashSet<Customer>(list);
    for (Customer customer : set) {
      System.out.println(customer);
    }
    tr.commit();

4. 左外連接配接查詢
  * 左外連接配接:  封裝成List<Object[]>
  
  * 迫切左外連接配接
    Session session = HibernateUtils.getCurrentSession();
    Transaction tr = session.beginTransaction();
    List<Customer> list = session.createQuery("from Customer c left join fetch c.linkmans").list();
    Set<Customer> set = new HashSet<Customer>(list);
    for (Customer customer : set) {
      System.out.println(customer);
    }
    tr.commit();      

隐式内連接配接

    select * from customers c,orders o where c.cid = o.cno;

左外連接配接

    select * from customers c left join orders o on c.cid = o.cno;

右外連接配接

    select * from customers c right join orders o on c.cid = o.cno;

左外連接配接,右外連接配接就是在簡單的連接配接查詢基礎上加個left join或right join罷了,表示以誰為主,為主的全查詢,

另一張表即使沒有與之比對的也以null填充

不大會考,直接粘貼之前代碼吧

package com.itheima.test;
 
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
 
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
 
import com.itheima.domain.Customer;
import com.itheima.domain.Linkman;
import com.itheima.utils.HibernateUtils;
 
/**
 * HQL的多表查詢
 * @author Administrator
 *
 */
public class Demo5 {
  
  /**
   * 查詢客戶聯系人資訊
   * select * from cst_customer c,cst_linkman l where c.id=l.id;
   */
  @Test
  public void run1(){
    Session session = HibernateUtils.getCurrentSession();
    Transaction tr = session.beginTransaction();
    
    //内連接配接的查詢    createQuery預設建立HQL接口(當然,這是Hibernate架構嘛)     建立其他接口就麻煩了createSQLQuery(原始sql語句查詢)
    Query query = session.createQuery("from Customer c inner join c.linkmans");
    //預設的傳回值還是Object數組
    List<Object[]> list = query.list();
    for (Object[] objects : list) {
      System.out.println(Arrays.toString(objects));
    }
    tr.commit();
  }
  
  /**
   * 資料預設傳回的數組,但可以自己設定,進而将資料封裝到對象中
   *   提供關鍵字:fetch 迫切連接配接
   */
  @Test
  public void run2(){
    Session session = HibernateUtils.getCurrentSession();
    Transaction tr = session.beginTransaction();
    
    //内連接配接的查詢    createQuery預設建立HQL接口(當然,這是Hibernate架構嘛)     建立其他接口就麻煩了createSQLQuery(原始sql語句查詢)
    Query query = session.createQuery("from Customer c inner join fetch c.linkmans");
    //預設的傳回值還是Object數組
    List<Customer> list = query.list();
    for (Customer c : list) {
      System.out.println(c);//toString方法要把linkmans給加上了  
    }
    
    tr.commit();
  }
  
  
  /**
   *   資料的重複問題
   * 手動解決,存入set即可去重
   */
  @Test
  public void run3(){
    Session session = HibernateUtils.getCurrentSession();
    Transaction tr = session.beginTransaction();
    
    //内連接配接的查詢    createQuery預設建立HQL接口(當然,這是Hibernate架構嘛)     建立其他接口就麻煩了createSQLQuery(原始sql語句查詢)
    Query query = session.createQuery("from Customer c inner join fetch c.linkmans");//和自己的集合連接配接
    //預設的傳回值還是Object數組
    List<Customer> list = query.list();
    Set<Customer> set=new HashSet<Customer>(list);
    for (Customer customer : set) {
      System.out.println(customer);//此時所屬聯系人已經封裝到Set<Linkman> linkmans集合中了
    }
    tr.commit();
  }
  
  
  /**
   * 左外連接配接
   * 和内連接配接一樣,把inner改成left即可
   */
  @Test
  public void run4(){
    Session session = HibernateUtils.getCurrentSession();
    Transaction tr = session.beginTransaction();
    
    //内連接配接的查詢    createQuery預設建立HQL接口(當然,這是Hibernate架構嘛)     建立其他接口就麻煩了createSQLQuery(原始sql語句查詢)
    Query query = session.createQuery("from Customer c left join fetch c.linkmans");//和自己的集合連接配接
    //預設的傳回值還是Object數組
    List<Customer> list = query.list();
    Set<Customer> set=new HashSet<Customer>(list);
    for (Customer customer : set) {
      System.out.println(customer);//此時所屬聯系人已經封裝到Set<Linkman> linkmans集合中了
    }
    tr.commit();
  }
 
}