1. 程式人生 > >Hibernate框架的學習-第二天

Hibernate框架的學習-第二天

原生sql sel 知識點 test 占位符 pre ber and 基本查詢

一、 hibernate中的實體規則

1. 實體類創建的註意事項

  1) 持久化類提供無參數構造

  2) 成員變量私有,提供共有get/set方法訪問.需提供屬性

  3) 持久化類中的屬性,應盡量使用包裝類型

  4) 持久化類需要提供oid.與數據庫中的主鍵列對應

  5) 不要用final修飾class

  hibernate使用cglib代理生成代理對象.代理對象是繼承被代理對象.如果被final修飾.將無法生成代理.

2. 主鍵類型

  1) 自然主鍵(少見)

  表的業務列中,有某業務列符合,必須有,並且不重復的特征時,該列可以作為主鍵使用.

  2) 代理主鍵(常見)

  表的業務列中,沒有某業務列符合,必須有,並且不重復的特征時,創建一個沒有業務意義的列作為主鍵

3. 主鍵生成策略

  1) 代理主鍵

  identity : 主鍵自增.由數據庫來維護主鍵值.錄入時不需要指定主鍵.

  sequence: Oracle中的主鍵生成策略.

  increment(了解): 主鍵自增.由hibernate來維護.每次插入前會先查詢表中id最大值.+1作為新主鍵值.

  hilo(了解): 高低位算法.主鍵自增.由hibernate來維護.開發時不使用.

  native:hilo+sequence+identity 自動三選一策略.

  uuid: 產生隨機字符串作為主鍵. 主鍵類型必須為string 類型.

  2) 自然主鍵

  assigned:自然主鍵生成策略. hibernate不會管理主鍵值.由開發人員自己錄入.

二、 hibernate中的對象狀態

  1. 對象分為三種狀態

   1) 瞬時狀態

    沒有id,沒有在session緩存中

  2) 持久化狀態

    有id,在session緩存中

  3) 遊離|托管狀態

    有id,沒有在session緩存中

  2. 三種狀態的轉換圖

技術分享

三、 hibernate進階-一級緩存

  1. 緩存:提高效率.hibernate中的一級緩存也是為了提高操作數據庫的效率.

  2. 提高效率手段1:提高查詢效率

  技術分享

  3. 提高效率手段2:減少不必要的修改語句發送

技術分享

四、 hibernate中的事務

  1. 事務

   1) 事務特性

     a 原子性

     c 一致性

     i 隔離性

     d 持久性

   2) 事務並發問題

    1.臟讀

    2.不可重復度

    3.幻|虛讀

   3) 事務的隔離級別

    1) 讀未提交- 123

    2) 讀已提交 - 23

    3) 可重復讀(mysql默認級別)-3

    4) 串行化 - 沒有問題

  2. 知識點:如何在hibernate中指定數據庫的隔離級別

技術分享

  3. 知識點2:在項目中如何管理事務

   1) 業務開始之前打開事務,業務執行之後提交事務. 執行過程中出現異常.回滾事務.

   2) 在dao層操作數據庫需要用到session對象.在service控制事務也是使用session對象完成. 我們要確保dao層和service層使用的使用同一個session對象

3) 在hibernate中,確保使用同一個session的問題,hibernate已經幫我們解決了. 我們開發人員只需要調用sf.getCurrentSession()方法即可獲得與當前線程綁定的session對象

   4) 註意1: 調用getCurrentSession方法必須配合主配置中的一段配置

技術分享

  5) 註意2:通過getCurrentSession方法獲得的session對象.當事務提交時,session會自動關閉.不要手動調用close關閉.

  4. 案例中的代碼實現:

1)service層

 public class CustomerServiceImpl implements CustomerService {

    private CustomerDao customerDao = new CustomerDaoImpl();

    public void save(Customer c) {
        Session session =  HibernateUtils.getCurrentSession();
        //打開事務
        Transaction tx = session.beginTransaction();
        //調用Dao保存客戶
        try {
            customerDao .save(c);
        } catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        }
        //關閉事務
        tx.commit();
    }
}

2)dao層

public class CustomerDaoImpl implements CustomerDao {

    public void save(Customer c) {
        //1 獲得session
        Session session = HibernateUtils.getCurrentSession();
        //3 執行保存
        session.save(c);
    }
}

五、hibernate中的批量查詢(概述)

  1. HQL查詢-hibernate Query Language(多表查詢,但不復雜時使用)

     Hibernate獨家查詢語言,屬於面向對象的查詢語言

1) 基本查詢

   /**
     * 基本查詢
     */
    @Test
    public void fun() {
        //1. 獲得session對象
        Session session = HibernateUtils.getSession();
        //2. 開啟事務並獲得操作事務的對象
        Transaction tx = session.beginTransaction();
        //3. 執行操作
        //1>書寫hql語句
        //String hql = "from com.java.domain.Customer";
        String hql = " from Customer "; //查詢所有的Customer對象
        //2>根據hql語句創建查詢對象
        Query query = session.createQuery(hql);
        //3>根據查詢對象獲得查詢結果
        List<Customer> list = query.list(); //返回list結果
        //Object result = query.uniqueResult(); //接收唯一的查詢結果
        System.out.println(list);
        //4. 提交事務並釋放資源
        tx.commit();
        session.close();
    }

   2)條件查詢

    /**
     * 條件查詢
     * HQL語句中,不出現與數據庫相關的
     */
    @Test
    public void fun2() {
        //1. 獲得session對象
        Session session = HibernateUtils.getSession();
        //2. 開啟事務並獲得操作事務的對象
        Transaction tx = session.beginTransaction();
        //3. 執行操作
        //1>書寫hql語句
        //String hql = "from com.java.domain.Customer";
        String hql = " from Customer where cust_id=1l "; //查詢所有的Customer對象
        //2>根據hql語句創建查詢對象
        Query query = session.createQuery(hql);
        //3>根據查詢對象獲得查詢結果
        Customer result = (Customer) query.uniqueResult(); //接收唯一的查詢結果
        System.out.println(result);
        //4. 提交事務並釋放資源
        tx.commit();
        session.close();
    }
  /**
     * 條件查詢
     * ?占位符
     */
    @Test
    public void fun3() {
        //1. 獲得session對象
        Session session = HibernateUtils.getSession();
        //2. 開啟事務並獲得操作事務的對象
        Transaction tx = session.beginTransaction();
        //3. 執行操作
        //1>書寫hql語句
        //String hql = "from com.java.domain.Customer";
        String hql = " from Customer where cust_id=? "; 
        //2>根據hql語句創建查詢對象
        Query query = session.createQuery(hql);
        //設置參數
        //query.setLong(0, 2l);
        query.setParameter(0, 2l);
        //3>根據查詢對象獲得查詢結果
        Customer result = (Customer) query.uniqueResult(); //接收唯一的查詢結果
        System.out.println(result);
        //4. 提交事務並釋放資源
        tx.commit();
        session.close();
    }
   /**
     * 條件查詢
     * 命名占位符
     */
    @Test
    public void fun4() {
        //1. 獲得session對象
        Session session = HibernateUtils.getSession();
        //2. 開啟事務並獲得操作事務的對象
        Transaction tx = session.beginTransaction();
        //3. 執行操作
        //1>書寫hql語句
        //String hql = "from com.java.domain.Customer";
        String hql = " from Customer where cust_id=:cust_id "; 
        //2>根據hql語句創建查詢對象
        Query query = session.createQuery(hql);
        //設置參數
        query.setParameter("cust_id", 3l);
        //3>根據查詢對象獲得查詢結果
        Customer c = (Customer) query.uniqueResult(); //接收唯一的查詢結果
        System.out.println(c);
        //4. 提交事務並釋放資源
        tx.commit();
        session.close();
    }

  3)分頁查詢

   /**
     * 分頁查詢
     * limit ?,?
     * query.setFirstResult(2); 
     * query.setMaxResults(2);
     */
    @Test
    public void fun5() {
        //1. 獲得session對象
        Session session = HibernateUtils.getSession();
        //2. 開啟事務並獲得操作事務的對象
        Transaction tx = session.beginTransaction();
        //3. 執行操作
        //1>書寫hql語句
        //String hql = "from com.java.domain.Customer";
        String hql = " from Customer "; //查詢所有的Customer對象
        //2>根據hql語句創建查詢對象
        Query query = session.createQuery(hql);
        
        //設置分頁信息 limit ?,?
        query.setFirstResult(2);
        query.setMaxResults(2);
        
        //3>根據查詢對象獲得查詢結果
        List<Customer> list = query.list();
        System.out.println(list);
        //4. 提交事務並釋放資源
        tx.commit();
        session.close();
    }

  2. Criteria查詢(單表條件查詢)

    Hibernate自創的無語句面向對象查詢

   1) 基本查詢

   /**
     * 基本查詢
     */
    @Test
    public void fun1() {
        //1. 獲得session對象
        Session session = HibernateUtils.getSession();
        //2. 開啟事務並獲得操作事務的對象
        Transaction tx = session.beginTransaction();
        //3. 執行操作
        
        //查詢所有的Customer對象
        Criteria criteria = session.createCriteria(Customer.class);
        List<Customer> list = criteria.list();
        System.out.println(list);
        
        //4. 提交事務並釋放資源
        tx.commit();
        session.close();
    }

  2)條件查詢

  條件查詢各個條件對應Criteria的函數API
   >    gt
   >=    ge
  <       lt
  <=       le
   ==       eq
  !=       ne
   in       in
   between and between
  in         in
   like       like
  is not null    isNotNull
   is null      isNull
  or        or
   and       and

  /**
     * 條件查詢
     * >                 gt
     * >=                ge
     * <                 lt
     * <=                le
     * ==                eq
     * !=                ne
     * in                in
     * between and       between
     * in                in
     * like              like
     * is not null       isNotNull
     * is null           isNull
     * or                or
     * and               and
     *
     */
    @Test
    public void fun2() {
        //1. 獲得session對象
        Session session = HibernateUtils.getSession();
        //2. 開啟事務並獲得操作事務的對象
        Transaction tx = session.beginTransaction();
        //3. 執行操作
        
        //創建criteris對象
        Criteria criteria = session.createCriteria(Customer.class);
        //添加查詢條件的參數  查詢cust_id為1的Customer對象
        //criteria.add(Restrictions.eq("cust_id", 1l));
        //Customer c = (Customer) criteria.uniqueResult();
        //System.out.println(c);
        
        //查詢cust_id在1和3之間的Customer對象
        criteria.add(Restrictions.between("cust_id", 1l, 3l));
        List<Customer> list = criteria.list();
        System.out.println(list);
        
        //4. 提交事務並釋放資源
        tx.commit();
        session.close();
    }

  3)分頁查詢

  /**
     *分頁查詢
     *  limit ?,?
     *    criteria.setFirstResult(3);
     *    criteria.setMaxResults(3);
     */
    @Test
    public void fun3() {
        //1. 獲得session對象
        Session session = HibernateUtils.getSession();
        //2. 開啟事務並獲得操作事務的對象
        Transaction tx = session.beginTransaction();
        //3. 執行操作
        
        //創建criteris對象
        Criteria criteria = session.createCriteria(Customer.class);
        //分頁查詢 limit ?,?
        criteria.setFirstResult(3);
        criteria.setMaxResults(3);
        List<Customer> list = criteria.list();
        System.out.println(list);
        
        //4. 提交事務並釋放資源
        tx.commit();
        session.close();
    }

  4)聚合函數

  /**
     * 聚合函數
     * criteria.setProjection(Projections.rowCount());
     *查詢總記錄數
     */
    @Test
    public void fun4() {
        //1. 獲得session對象
        Session session = HibernateUtils.getSession();
        //2. 開啟事務並獲得操作事務的對象
        Transaction tx = session.beginTransaction();
        //3. 執行操作
        
        //創建criteris對象
        Criteria criteria = session.createCriteria(Customer.class);
        //設置查詢的聚合函數  總行數
        criteria.setProjection(Projections.rowCount());
        //執行查詢
        Long count = (Long) criteria.uniqueResult();
        System.out.println(count);
        
        //4. 提交事務並釋放資源
        tx.commit();
        session.close();
    }

  3. 原生SQL查詢(復雜的業務查詢)

   1) 基本查詢

  /**
     * 基本查詢
     */
    @Test
    public void fun1() {
        //1. 獲得session對象
        Session session = HibernateUtils.getSession();
        //2. 開啟事務並獲得操作事務的對象
        Transaction tx = session.beginTransaction();
        //3. 執行操作
        
        //1>. 書寫sql語句
        String sql = "select * from cst_customer";
        //2>. 創建sql語句的查詢對象
        SQLQuery query = session.createSQLQuery(sql);
        //3>. 執行查詢操作
        List<Object[]> list = query.list();
        for(Object[] objs : list) {
            System.out.println(Arrays.toString(objs));
        }
        //4. 提交事務並釋放資源
        tx.commit();
        session.close();
        
    }
  /**
     * 基本查詢
     * 指定將結果封裝到哪個對象中去
     * query.addEntity(Customer.class);
     */
    @Test
    public void fun2() {
        //1. 獲得session對象
        Session session = HibernateUtils.getSession();
        //2. 開啟事務並獲得操作事務的對象
        Transaction tx = session.beginTransaction();
        //3. 執行操作
        
        //1>. 書寫sql語句
        String sql = "select * from cst_customer";
        //2>. 創建sql語句的查詢對象
        SQLQuery query = session.createSQLQuery(sql);
        //指定將結果封裝到哪個對象中去
        query.addEntity(Customer.class);
        //3>. 執行查詢操作
        List<Customer> list = query.list();
        System.out.println(list);
        //4. 提交事務並釋放資源
        tx.commit();
        session.close();
    }

  2)條件查詢

  /**
     * 條件查詢
     */
    @Test
    public void fun3() {
        //1. 獲得session對象
        Session session = HibernateUtils.getSession();
        //2. 開啟事務並獲得操作事務的對象
        Transaction tx = session.beginTransaction();
        //3. 執行操作
        
        //1>. 書寫sql語句
        String sql = "select * from cst_customer where cust_id=?";
        //2>. 創建sql語句的查詢對象
        SQLQuery query = session.createSQLQuery(sql);
        //設置?占位符的參數
        query.setParameter(0, 5l);
        //指定將結果封裝到哪個對象中去
        query.addEntity(Customer.class);
        
        //3>. 執行查詢操作
        Customer c = (Customer) query.uniqueResult();
        System.out.println(c);
        //4. 提交事務並釋放資源
        tx.commit();
        session.close();
    }

  3)分頁查詢

  /**
     * 分頁查詢
     */
    @Test
    public void fun4() {
        //1. 獲得session對象
        Session session = HibernateUtils.getSession();
        //2. 開啟事務並獲得操作事務的對象
        Transaction tx = session.beginTransaction();
        //3. 執行操作
        
        //1>. 書寫sql語句
        String sql = "select * from cst_customer limit ?,?";
        //2>. 創建sql語句的查詢對象
        SQLQuery query = session.createSQLQuery(sql);
        //設置?占位符的參數
        query.setParameter(0, 2);
        query.setParameter(1, 2);
        //指定將結果封裝到哪個對象中去
        query.addEntity(Customer.class);
        
        //3>. 執行查詢操作
        List<Customer> list = query.list();
        System.out.println(list);
        //4. 提交事務並釋放資源
        tx.commit();
        session.close();
    }

Hibernate框架的學習-第二天