Hibernate框架的學習-第二天
一、 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框架的學習-第二天