天天看點

Hibernate學習第四天筆記1、上次課回顧2、Hibernate的查詢的方式

1、上次課回顧

1.1 hibernate的一對多

  • 表與表之間的關系
    • 一對多關系
    • 多對多關系
    • 一對一關系
  • hibernate的一對多配置 - 搭建hibernate基本環境 - 建立表 - 建立實體 - 一的一方 - 方的是多的一方的集合 - 多的一方 - 方的是一的一方的集合 - 建立映射 - 一的一方 - 配置的是set集合 - 多的一方 - 配置<many-to-one/> - 必須呢測試類
  • hibernate的一對多的操作
    • 級聯操作 :cascade,用于操作其關聯的對象
      • 級聯儲存或更新
      • 級聯删除
    • 測試對象導航
    • 放棄外鍵維護權 :inverse:使用者控制是否有外鍵維護能力

1.2 hibernate的多對多

  • hibernate多對多的配置
    • 搭建hibernate環境
    • 建立表
    • 建立實體
      • 放置的是對方的集合
    • 建立映射
      • 放置的是對象的
    • 編寫測試類
  • hibernate多對多的操作
    • 級聯操作
      • 級聯儲存或更新
      • 級聯删除(了解即可)
    • 其他的操作
      • 給使用者選擇角色
      • 給使用者修改角色
      • 給使用者删除角色

2、Hibernate的查詢的方式

2.1 OID查詢

OID檢索:hibernate根據對象的OID(主鍵)進行檢索。

2.1.1 使用get方法

Customer customer = session.get(Customer.class,1l);
           

2.1.2 使用load方法

Customer customer = session.get(Customer.class,1l);
           

2.2 對象導航檢索

對象導航檢索:Hibernate根據一個已經查詢到的對象,獲得其關聯的對象的一種查詢方式。
LinkMan linkMan = Session.get(LinkMan.class,1l);
Customer customer = linkMan.getCustomer();

Customer customer =  session.get(Customer.class,2l);
List<LinkMan> linkmans = customer.getLinkMans();
           

2.3 HQL檢索

HQL查詢:Hibernate Query Language(Hibernate的查詢語言),是一種面向對象的方式的查詢語言,文法類似SQL。通過session.createQuery(),用于接收一個進行查詢的一種方式。
  • 初始化一些資料
    • 建立表
    • 建立對象

2.3.1 HQL的簡單查詢

public void demo2() {
    Session session = HibernateUtils.getCurrentSession();
    Transaction transaction = session.beginTransaction();
    String hql = "from Customer";
    Query query = session.createQuery(hql);
    List<Customer> list = query.list();
    for (Customer customer : list) {
        System.out.println(customer);
    }
    transaction.commit();
}
           

2.3.2 HQL的排序查詢

/***
 * HQL的排序查詢
 */
@Test
public void demo3() {
    Session session = HibernateUtils.getCurrentSession();
    Transaction transaction = session.beginTransaction();
    //預設情況:升序查詢
    //List<Customer> list = session.createQuery("from Customer order by cust_id").list();
    //設定降序排序
    List<Customer> list = session.createQuery("from Customer order by cust_id desc").list();
    for (Customer customer : list) {
        System.out.println(customer);
    }
    transaction.commit();
}
           
需要注意的是:我用的hibernate版本是5.4.1,在?後面加上數字0,1,1....。;老版本不需要加。

2.3.3 HQL的條件查詢

/***
 * HQL的條件查詢
 */
@Test
public void demo4() {
    Session session = HibernateUtils.getCurrentSession();
    Transaction transaction = session.beginTransaction();
    //條件查詢
    //1、按位置綁定:根據參數的位置進行綁定
    //一個條件
    /*
     * Query query = session.createQuery("from Customer where cust_name=?0");
     * query.setParameter(0, "雷軍"); List<Customer> list = query.list();
     */

    //多個條件
    /*
     * Query query = session.createQuery("from Customer where cust_id=?0 and cust_name like ?1");
     * query.setParameter(0, 1l); query.setParameter(1, "雷%"); 
     * List<Customer> list = query.list();
     */

    //2、按名稱綁定
    Query query = session.createQuery("from Customer where cust_id= :aaa and cust_name like :name");
    query.setParameter("aaa", 2l);
    query.setParameter("name", "雷%");
    List<Customer> list = query.list();
    for (Customer customer : list) {
        System.out.println(customer);
    }


    transaction.commit();
}
           

2.3.4 HQL的投影查詢

投影查詢:查詢對象的某個或某些屬性
/**
 * 投影查詢:查詢對象的某個或某些屬性
 */
@Test
public void demo5() {
    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); }
     */

    //多個屬性
    /*
     * List<Object[]> list =
     * session.createQuery("select c.cust_id,c.cust_name from Customer c").list();
     * for (Object[] objects : list) { System.out.println(Arrays.toString(objects));
     * }
     */

    //查詢多個屬性:但是我們想封裝到對象中
    List<Customer> list = session.createQuery("select new Customer(cust_id,cust_name) from Customer").list();
    for (Customer customer : list) {
        System.out.println(customer);
    }
    transaction.commit();
}
           

2.3.5 HQL的分組統計查詢

/**
 * 分組統計查詢
 */
@Test
public void demo7() {
    Session session = HibernateUtils.getCurrentSession();
    Transaction transaction = session.beginTransaction();

    //uniqueResult():唯一結果,隻能查到一個值
    //聚合函數的使用:count(),max(),min(),avg(),sum()
    /*
     * Object object= (Long)
     * session.createQuery("select count(*) from Cutomer").uniqueResult();
     * System.out.println(object);
     */

    //分組統計
    List<Object[]> list = session.createQuery("select cust_source,count(*) from Customer group by cust_source").list();

    //大于等于2的
    //List<Object[]> list = session.createQuery("select cust_source,count(*) from Customer group by cust_source having count(*) >=2").list();
    for (Object[] objects : list) {
        System.out.println(Arrays.toString(objects));
    }

    transaction.commit();
}
           

2.3.6 HQL的分頁查詢

* 分頁查詢
 */
@Test
public void demo6() {
    Session session = HibernateUtils.getCurrentSession();
    Transaction transaction = session.beginTransaction();

    Query query = session.createQuery("from LinkMan");
    query.setFirstResult(3);        //起始位置
    query.setMaxResults(5);         //每頁資料條數
    List<LinkMan> list = query.list();

    for (LinkMan linkMan : list) {
        System.out.println(linkMan);
    }

    transaction.commit();
}
           

2.3.7 多表查詢

  • SQL的多表查詢
    • 連接配接查詢
      • 交叉連接配接
      • 内連接配接
        • 隐式内連接配接
        • 顯式内連接配接
      • 外連接配接
        • 左外連接配接
        • 右外連接配接
    • 子查詢
  • HQL的多表查詢
    • 連接配接查詢
      • 交叉連接配接
      • 内連接配接
        • 顯式内連接配接
        • 隐式内連接配接
        • 迫切内連接配接
      • 外連結
        • 左外連接配接
        • 右外連接配接
        • 迫切左外連接配接
代碼如下
/**
 * HQL多表查詢
 */
@Test
public void demo8() {
    Session session = HibernateUtils.getCurrentSession();
    Transaction transaction = 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)); }
     */

    //迫切内連接配接:其實就是在普通的内連接配接inner join 後添加一個關鍵字fetch
    List<Customer> customers = session.createQuery("select distinct c from Customer c inner join fetch c.linkMans ").list();//通知Hibernate,将另一個對象的資料封裝到該對象中
    for (Customer customer : customers) {
        System.out.println(customer);
    }
    transaction.commit();

}           
           

2.4 QBC檢索

QBC:Query By Criteria,條件查詢:是一種更加面向對象化的查詢方式。

2.4.1 簡單查詢

/**
 * 簡單查詢
 */
@Test
public void demo1() {
    Session session = HibernateUtils.getCurrentSession();
    Transaction transaction = session.beginTransaction();

    //獲得criteria的對象
    Criteria criteria = session.createCriteria(Customer.class);
    List<Customer> list = criteria.list();
    for (Customer customer : list) {
        System.out.println(customer);
    }

    transaction.commit();
}
           

2.4.2 排序查詢

/**
 * 排序查詢
 */
@Test
public void demo2() {
    Session session = HibernateUtils.getCurrentSession();
    Transaction transaction = session.beginTransaction();

    //獲得criteria的對象
    Criteria criteria = session.createCriteria(Customer.class);
    //Order是hibernate中的一個對象
    criteria.addOrder(Order.desc("cust_id"));
    List<Customer> list = criteria.list();
    for (Customer customer : list) {
        System.out.println(customer);
    }

    transaction.commit();
}
           

2.4.3 分頁查詢

/*
 * 分頁查詢
 */
@Test
public void demo3() {
    Session session = HibernateUtils.getCurrentSession();
    Transaction transaction = session.beginTransaction();

    //獲得criteria的對象
    Criteria criteria = session.createCriteria(LinkMan.class);
    criteria.setFirstResult(3);
    criteria.setMaxResults(5);
    List<LinkMan> list = criteria.list();
    for (LinkMan linkMan : list) {
        System.out.println(linkMan);
    }

    transaction.commit();
}
           

2.4.4 條件查詢

/*
 * 分頁查詢
 */
@Test
public void demo4() {
    Session session = HibernateUtils.getCurrentSession();
    Transaction transaction = session.beginTransaction();

    //獲得criteria的對象
    Criteria criteria = session.createCriteria(Customer.class);

    /**
     *  設定條件:
     *  ==  eq (equals)
     *  >   gt (greater than)
     *  >=  ge (greater equals)
     *  <   lt (less than)
     *  <=  le (less equals)
     *  <>  ne (not equals)
     *  like
     *  in
     *  between
     *  and
     *  or
     */
    criteria.add(Restrictions.eq("cust_source", "影視"));
    criteria.add(Restrictions.like("cust_name", "雷%"));
    //criteria.add(Restrictions.or(Restrictions.like("cust_name", "雷%")));
    List<Customer> list = criteria.list();
    for (Customer customer : list) {
        System.out.println(customer);
    }

    transaction.commit();
}
           

2.4.5 統計查詢

/*
 *  統計查詢
 */
@Test
public void demo5() {
    Session session = HibernateUtils.getCurrentSession();
    Transaction transaction = session.beginTransaction();

    //擷取Criteria的對象
    Criteria criteria = session.createCriteria(Customer.class);

    /**
     * add              :普通的條件,where後面的條件
     * addOrder         :排序
     * setProjection    :聚合函數和group by ,having 後面的條件
     */
    criteria.setProjection(Projections.rowCount());
    Long num = (Long) criteria.uniqueResult();
    System.out.println(num);
    transaction.commit();
}
           

2.4.6 離線條件查詢(SSH)-->DetachedCriteria

使用DetachedCriteria-->離線(脫離session)
/*
   *  離線條件查詢
 */
@Test
public void demo6() {
    DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Customer.class);
    detachedCriteria.add(Restrictions.like("cust_name", "雷%"));

    Session session = HibernateUtils.getCurrentSession();
    Transaction transaction = session.beginTransaction();

    Criteria criteria = detachedCriteria.getExecutableCriteria(session);
    List<Customer> list = criteria.list();
    for (Customer customer : list) {
        System.out.println(customer);
    }
    transaction.commit();

}
           

2.5 SQL檢索

@Test
public void demo1() {
    Session session = HibernateUtils.getCurrentSession();
    Transaction transaction = session.beginTransaction();

    /*
     * List<Object[]> list =
     * session.createSQLQuery("select * from cst_customer").list(); for (Object[]
     * objects : list) { System.out.println(objects); }
     */

    SQLQuery query = session.createSQLQuery("select * from cst_customer");
    query.addEntity(Customer.class);
    List<Customer> list = query.list();
    for (Customer customer : list) {
        System.out.println(customer);
    }
    transaction.commit();
}
           

3、Hibernate的抓取政策

3.1延遲加載

3.1.1延遲加載的概述

延遲加載:lazy(懶加載)。執行到該行代碼的時候,不會馬上送語句去進行查詢,在真正使用這個對象的屬性的時候才會發送SQL語句進行查詢。

3.2延遲加載的分類

3.2.1類級别的延遲加載

值的是通過load方法查詢某個對象的時候,是否采用延遲。session.load(Customer.class)
  • 配置
    • 在配置檔案的class标簽中設定lazy為true或者false,預設為true.
  • 讓lazy失效
    • 将lazy設定為false
    • 将持久化類使用 final修飾
    • hibernate.initialize(Customer)

3.2.2關聯級别的延遲加載

值的是在查詢到某個對象的時候,查詢其關聯的對象的時候,是否采用延遲加載。Customer customer = session.get(Customer.class);

3.2 抓取政策

3.2.1 抓取政策的概述

  • 通過一個對象抓取到關聯對象需要發送SQL語句,SQL語句如何發送,發送成什麼格式通過政策進行配置。
    • 通過或者<many-to-one>上通過fetch屬性進行設定。
    • fetch和這些标簽上的lazy如何設定優化發送的SQL語句。

3.2.1.1 上的fetch和lazy

  • fetch:抓取政策,控制SQL語句格式
    • select :預設值,發送普通的select語句,查詢關聯對象
    • join :發送一條迫切左外連接配接查詢關聯對象
    • subselect :發送一條子查詢查詢其關聯的額對象
  • lazy: 延遲加載,控制查詢關聯對象的時候是否采用延遲
    • true :預設值,查詢關聯對象的時候,采用延遲加載
    • false :查詢關聯對象的時候,不采用延遲加載
    • extra :及其懶惰,

3.2.1.2 <many-to-one>上的fetch和lazy

  • fetch:抓取政策:控制SQL語句格式
    • select :預設,發送普通的select語句,查詢關聯對象
    • join :發送一條迫切左外連接配接。
  • lazy:延遲加載,控制查詢關聯對象的時候是否采用延遲加載
    • proxy :預設,
    • false :查詢關聯對象,不采用延遲加載
    • no-proxy(不會使用)