【部份內容參考地址:http://www.javashuo.com/article/p-rvqqxzky-dt.html】html
Hibernate是一個開放源代碼的對象關係映射框架,它對JDBC進行了很是輕量級的對象封裝,它將POJO與數據庫表創建映射關係,是一個全自動的orm框架,hibernate能夠自動生成SQL語句,自動執行,使得Java程序員能夠爲所欲爲的使用對象編程思惟來操縱數據庫。 Hibernate能夠應用在任何使用JDBC的場合,既能夠在Java的客戶端程序使用,也能夠在Servlet/JSP的Web應用中使用,最具革命意義的是,Hibernate能夠在應用EJB的J2EE架構中取代CMP,完成數據持久化的重任。程序員
一、經過Configuration config=new Configuration().configure(); //讀取並解析hibernate.cfg.xml配置文件sql
二、由hibernate.cfg.xml中的<mapping resource="com/xx/User.hbm.xml"/> //讀取並映射信息數據庫
三、經過SessionFactory sf = config.buildSessionFactory(); //建立SessionFactory編程
四、Session s = sf.openSession(); //打開session數組
五、Transaction tx = s.beginTransaction(); //建立並啓動事務Transaction緩存
六、persistent operate操做數據,持久化操做session
七、tx.commit(); //提交事務架構
八、關閉Session併發
九、關閉SessionFactory
一、獲取SessionFactory
二、經過SessionFactory 獲取一個Session
三、在Session基礎上開啓一個事務
四、經過調用Session的save方法把對象保存到數據庫
五、 提交事務
六、關閉Session
七、關閉SessionFactory
1 public class TestHibernate { 2 3 public static void main(String[] args) { 4 5 //獲取SessionFactory 6 SessionFactory sf = new Configuration().configure().buildSessionFactory(); 7 8 Session s = sf.openSession(); //經過SessionFactory 獲取一個Session 9 s.beginTransaction(); //在Session基礎上開啓一個事務 10 11 Catagory c = new Catagory(); 12 c.setName("分類1"); 13 s.save(c); //經過調用Session的save方法把對象保存到數據庫 14 15 s.getTransaction().commit(); //提交事務 16 s.close(); //關閉Session 17 sf.close(); //關閉SessionFactory 18 } 19 20 }
一、對JDBC訪問數據庫的代碼封裝,大大簡化了數據訪問層繁瑣的重複代碼。
二、hibernate是輕量級框架,支持各類數據庫,從一對一到一對多的各類複雜關係。
hibernate的緩存包括兩大類:一級緩存(session緩存)和二級緩存(SessionFactory緩存)。
一級緩存:一級緩存是內置的,就是說只要你使用hibernate就必須使用session緩存。hibernate默認是開啓一級緩存的。因爲session對象的聲明週期一般對應一個數據庫事務或者一個應用事務,所以其緩存的緩存範圍是事務。在一級緩存中,持久化類的每一個實例都具備惟一的OID(對象標識符)。
二級緩存:因爲二級緩存對象的生命週期和應用程序的整個過程對應,所以hibernate二級緩存的緩存範圍是進程或者集羣,有可能出現併發問題,所以須要採起適當的併發訪問策略,該策略爲被緩存的數據提供了事務隔離級別。二級緩存是可選的,是一個可配置的插件,默認狀況下不會啓動。若要開啓二級緩存,能夠在hibernate.cfg.xml中開啓二級緩存的配置,hibernate自己不提供二級緩存,都是使用第三方的二級緩存插件,可使用 EhCache提供的二級緩存。
應該放在二級緩存中的數據:
一、不多被修改的數據
二、不是很重要的數據,容許出現偶爾併發的數據
三、不會被併發訪問的數據
四、常量數據
不適合放在二級緩存中的數據:
一、常常被修改的數據
二、不容許出現併發訪問的數據
三、與其餘應用共享的數據
一、使用雙向一對多關聯,不適用單向。
二、使用一對多取代一對一
三、配置對象緩存,不適用集合緩存
延遲加載 又叫 lazyload。
get是非延遲加載,不管後面的代碼是否會訪問到屬性,立刻執行sql語句,對於不存在的對象返回null【處理對象是null,處理空對象的信息也會拋出異常】。
load是延遲加載,只有屬性被訪問到的時候,纔會執行sql語句,對於不存在的對象會拋出異常。
屬性的延遲加載:
當使用load方式來獲取對象的時候,只有訪問了這個對象的屬性,hibernate纔會到數據庫中進行查詢,不然不會訪問數據庫。
關係的延遲加載:
關係的延遲加載在one-many、many-many的時候均可以使用。
使用 session的createSQLQuery方法執行標準sql語句時,因爲標準sql語句可能有多種返回結果,不能保證其查詢結果能夠裝進一個Product對象中,因此返回的集合裏的每個元素是一個對象數組。
1 String name = "iphone"; 2 String sql = "select * from product_ p where p.name like '%"+name+"%'"; 3 Query q = s.createSQLQuery(sql); 4 List<Object[]> list = q.list(); 5 for(Object[] os : list) { 6 for(Object o : os) { 7 System.out.print(o + "\t"); 8 } 9 System.out.println(); 10 }
使用hql查詢數據時,根據hql建立一個Query對象,設置參數,(PreparedStatement:基1,Query:基0),經過Query對象的list()方法返回查詢結果。
【注:使用hql時,使用的是類名,而不是表名】
【注:使用hql時,不須要在前面加select *】
1 String name = "iphone"; 2 Query q = s.createQuery("from Product p where p.name like ?"); 3 q.setString(0, "%"+name+"%"); 4 List<Product> ps = q.list(); 5 for(Product p : ps) { 6 System.out.println(p.getPrice()); 7 }
使用Criteria查詢數據時,徹底面向對象,再也不有sql語句的痕跡。(Criteria還能夠很方便的進行分頁查詢和獲取總數)
經過session的creteCriteria建立一個Criteria對象,Criteria.add增長約束,調用list()方法返回查詢結果的集合。
1 String name = "iphone"; 2 Criteria c = s.createCriteria(Product.class); 3 c.add(Restrictions.like("name", "%"+name+"%")); 4 List<Product> ps = c.list(); 5 for(Product p : ps) { 6 System.out.println(p.getPrice()); 7 }
使用Criteria分頁查詢數據時,不管你使用的是Oracle,Mysql,NoSQL仍是DB2,分頁查詢的代碼寫法都是同樣的。
c.setFirstResult(2); 表示從第3條數據開始 。
c.setMaxResults(5); 表示一共查詢5條數據。
1 String name = "iphone"; 2 Criteria c = s.createCriteria(Product.class); 3 c.add(Restrictions.like("name", "%" + name + "%")); 4 c.setFirstResult(2); 5 c.setMaxResults(5); 6 7 List<Product> pl = c.list(); 8 for(Product p : pl) { 9 System.out.println(p.getName()); 10 }
Hibernate有兩種方式得到session,分別是:openSession和getCurrentSession
區別:一、獲取的是不是同一個session對象
openSession每次都會獲得一個新的Session對象 。
getCurrentSession在同一個線程中,每次都是獲取相同的Session對象,可是在不一樣的線程中獲取的是不一樣的Session對象 。
二、事務提交的必要性
openSession只有在增長,刪除,修改的時候須要事務,查詢時不須要的 。
getCurrentSession是全部操做都必須放在事務中進行,而且提交事務後,session就自動關閉,不可以再進行關閉。
創建數據庫鏈接時比較消耗時間的,因此一般都會採用數據庫鏈接池的技術來創建多條數據庫鏈接,而且在未來持續使用,從而節約掉創建數據庫鏈接的時間 。
hibernate自己是提供了數據庫鏈接池的,可是hibernate官網也不推薦使用他自帶的數據庫鏈接池。 通常都會使用第三方的數據庫鏈接池。C3P0是免費的第三方的數據庫鏈接池,而且有不錯的表現 。
【注:當運行次數不大的時候,從運行效果上來看,是看不出區別的。 只有在高併發量的狀況下,纔會體會出來。】
XML配置方式:
優:容易編輯,配置比較集中,方便修改,在大業務量的系統裏面,經過xml配置會方便後人理解整個系統的架構,修改以後直接重啓應用便可 。
缺:比較繁瑣,配置形態醜陋, 配置文件過多的時候難以管理 。
註解方式:
優:方便,簡潔,配置信息和 Java 代碼放在一塊兒,有助於加強程序的內聚性。
缺:分散到各個class文件中,因此不宜維護, 修改以後你須要從新打包,發佈,重啓應用。
總結:
=> 小項目,參與人數很少,不復雜的用註解,開發快速。
=>複雜項目,多人交互,配置量大,維護複雜度高的,用配置文件。