天天看點

hibernate3入門

Hibernate入門                                 ++YONG原創,轉載請聲明 1.    應用程式的分層體系結構: 1.1.       典型的三層結構: 1.1.1.       表示層:提供資料輸入、檢驗與資料呈現的應用程式元件。(GUI、web頁面)。就是與使用者打交道的UI界面。 1.1.2.       業務層:提供商業邏輯服務的應用程式元件。 1.1.3.       資料層:負責存放和管理應用的持久性業務資料的持久化存儲系統。(Database、XML),最常見的持久化存儲系統就是廣泛使用的關系資料庫。 1.2.       軟體層的特征: 1.2.1.       每個層由一組相關的類或元件構成,共同完成特定的功能。 1.2.2.       層與層之間存在自上而下的依賴關系。即上層元件會通路下層元件的API,而下層元件不應該依賴上層元件。如:表現層依賴于業務邏輯層,而業務邏輯層依賴于資料層。 1.2.3.       每個層對上層公開API,封裝實作細節。當某一層的實作發生改變,隻要它的API不變,不會影響其他層的實作。 1.3.       軟體分層的優點: 1.3.1.       伸縮性強:能支援更多的使用者。 1.3.2.       可維護性高:修改軟體的某一層的實作,不會影響其他層。 1.3.3.       可擴充性強:增加新功能更容易,每個層中都有擴充點,不會打破應用的整體架構。 1.3.4.       可重用性高:同一程式能滿足多種需求。 1.3.5.       可管理性高:工作、管理子產品化。 1.4.       四層結構: 由于資料存儲方式多樣,業務層不僅要負責業務邏輯的處理,還要跟資料層互動,提供對業務資料的CRUD操作(create、retrieve、update、delete)。為了把業務資料通路細節和業務邏輯分開,把業務資料通路作為單獨的持久層。是以目前流行的軟體分層結構是: 1.         表示層: 2.         業務層:業務邏輯層負責完成應用程式的邏輯功能,包括 調用持久層完成實體對象的存取、安全檢查,事務控制等。抽象出業務邏輯層的好處是将應用程式的邏輯功能從表示層中剝離,這樣就能複用邏輯層的功能。此外,業務邏輯層也可以看作是對持久層的一個門面模式,簡化表示層對這些邏輯功能的調用。 3.         持久層:封裝了業務資料通路細節,為業務層提供了面向對象的API。 持久層負責實作所有的資料通路功能,它将上層傳入的資料寫入到持久化存儲系統中,并根據上層的要求讀取或修改現有的資料。 4.         資料層: 1.5.       完善的持久層應該達到以下目标: l 代碼可重用性高,能夠完成所有的資料通路操作。 l 具有相對獨立性,當持久層的實作細節發生變化,不會影響上層的實作。 2.    ORM簡介: 1.       ORM(Object-Relation Mapping)對象-關系映射模式指的是在單個元件中負責所有實體域對象的持久化,封裝資料通路的細節。 2.       Hibernate就是一個開源的ORM中間件。(官方網站: http://www.hibernate.org/) 3.    Hibernate簡介: 2001年未 Hibernate 第一個版本發表,2003年6月8日 Hibernate 2 發表,并于年未獲得 Jolt 2004 大獎,後被 JBOSS 收納而成為其子項目之一,2005年3月 Hibernate 3 正式發表,當中有了一些重大的改變,本文使用的版本為Hibernate 3.2。 4.    配置 hibernate: 4.1.       準備好所需的jar包: 到官方網站: http://www.hibernate.org/6.html 下載下傳(目前版本:Hibernate Core 3.2.3GA ) hibernate包。解開壓縮包。在lib目錄下找到以下hibernate應用所必須的包(可以檢視該目錄下的_README.txt檔案來确定哪些包是必需的): 1.       hibernate.jar :hibernate核心包。必需的。 2.       antlr.jar :Hibernate使用ANTLR來産生查詢分析器,這個類庫在運作環境下時也是必需的。 3.       cglib.jar :CGLIB庫,Hibernate用它來實作PO位元組碼的動态生成,非常核心的庫,必需的jar包。 4.       asm.jar :ASM位元組碼庫,cglib.jar包依賴的包。必需的jar包。 5.       asm-attrs.jar :ASM位元組碼庫,cglib.jar包依賴的包。必需的jar包。 6.       commons-collections.jar :Apache Commons包中的一個,包含了一些Apache開發的集合類,功能比java.util.*強大。必須使用的jar包。 7.       commons-logging.jar :Apache Commons包中的一個,包含了日志功能,必須使用的jar包。這個包本身包含了一個Simple Logger,但是功能很弱。在運作的時候它會先在CLASSPATH找log4j,如果有,就使用log4j,如果沒有,就找JDK1.4帶的java.util.logging,如果也找不到就用Simple Logger。必需的。 8.       ehcache.jar :Hibernate可以使用不同cache緩存工具作為二級緩存。EHCache是預設的cache緩存工具。如果沒有其它的可選緩存工具,則為必需的。 9.       jta.jar :JTA規範,當Hibernate使用JTA的時候需要。必需的。 10.   dom4j.jar :dom4j是一個Java的XML API,類似于jdom,用來讀寫XML檔案的。Hibernate使用dom4j解析XML配置檔案和XML映射元檔案。必需的。 11.   log4j.jar :日志包,可選的。 把以上必需的jar放置到應用程式的類路徑中(web應用的WEB-INF/lib目錄下)。 4.2.       基本的Hibernate配置檔案: 在WEB-INF/classes目錄下建立一hibernate.cfg.xml(在官方下載下傳的包etc目錄下有樣闆檔案):

<? xml version = "1.0" encoding = "utf-8" ?> <! DOCTYPE hibernate-configuration PUBLIC     "-//Hibernate/Hibernate Configuration DTD 3.0//EN"     "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd" > < hibernate-configuration >     < session-factory >         <!-- 資料庫連接配接設定 -->         < property name = "connection.driver_class" >             com.mysql.jdbc.Driver         </ property >         < property name = "connection.url" >             jdbc:mysql://localhost:3306/demo         </ property >         < property name = "connection.username" > root </ property >         < property name = "connection.password" > root </ property >         <!-- SQL 方言 -->         < property name = "dialect" > org.hibernate.dialect.MySQLInnoDBDialect </ property >         <!-- 實際操作資料庫時是否顯示 SQL -->         < property name = "show_sql" > true </ property >          <!-- 将資料庫 schema 的 DDL 導出到資料庫 --> <!-- property name = "hibernate.hbm2ddl.auto" > create </ property!-- >           <!-- 以下設定對象與資料庫表的映像檔案 -->         ......     </ session-factory > </ hibernate-configuration >

5.    第一個Hibernate應用程式: 5.1.       建立一個持久化類: 持久化類就是其執行個體要被持久化到資料庫中的類,通常都是實體域類,它是帶有一些屬性及屬性的getters、setters方法的POJO類:

package org.qiujy.demo;   public class User {     private Integer id ;     private String name ;     private Integer age ;         public User(){}       public Integer getAge() {         return age ;     }       public void setAge(Integer age) {         this . age = age;     }       public Integer getId() {         return id ;     }       public void setId(Integer id) {         this . id = id;     }       public String getName() {         return name ;     }       public void setName(String name) {         this . name = name;     } }

5.2.       準備好資料庫表: 在MySQL中新增一個demo資料庫,并建立user表:

CREATE TABLE user (     id INT(11) NOT NULL auto_increment PRIMARY KEY,     name VARCHAR(100) NOT NULL default '',     age INT );

5.3.       建立對象-關系映射檔案: Hibernate需要知道怎樣去加載(load)和存儲(store)持久化類的對象。這正是Hibernate映射檔案發揮作用的地方。映射檔案告訴Hibernate應該通路資料庫(database)裡面的哪個表(table)以及應該使用表裡面的哪些字段(column)。 在持久化類所在的包的目錄下建立一名為User.hbm.xml的映射檔案:

<? xml version = "1.0" encoding = "utf-8" ?> <! DOCTYPE hibernate-mapping PUBLIC         "-//Hibernate/Hibernate Mapping DTD 3.0//EN"         "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >   < hibernate-mapping >     < class name = "org.qiujy.demo.User" table = "user" >         < id name = "id" column = "id" type = "java.lang.Integer" >             < generator class = "native" />         </ id >         < property name = "name" column = "name" type = "java.lang.String" />         < property name = "age" column = "age" type = "java.lang.Integer" />     </ class > </ hibernate-mapping >

5.4.       在Hibernate配置檔案hibernate.cfg.xml中指明映射檔案的位置:

< session-factory > <!-- 以下設定對象與資料庫表的映像檔案 -->     < mapping resource = "org/qiujy/demo/User.hbm.xml" /> </ session-factory >

5.5.       使用Hibernate API進行持久化操作: 1.       建立一輔助類:由這個輔助類來建立一個線程安全的、全局的SessoinFactory,SessionFactory可以建立并打開新的單線程的Session。

package org.qiujy.common;   import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration;   public class HibernateSessionFactory {           private static String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml";              private static final ThreadLocal threadLocal = new ThreadLocal();                   private static final ThreadLocal txThreadLocal = new ThreadLocal();     private static Configuration configuration = new Configuration();     private static org.hibernate.SessionFactory sessionFactory;     private static String configFile = CONFIG_FILE_LOCATION;       private HibernateSessionFactory() {     }                       public static Session getSession() throws HibernateException {         Session session = (Session) threadLocal.get();                      if (session == null || !session.isOpen()) {                             if (sessionFactory == null) {                                      rebuildSessionFactory();                             }                             session = (sessionFactory != null) ? sessionFactory.openSession()                                                : null;                             threadLocal.set(session);                    }           return session;     }                     public static void rebuildSessionFactory() {                    try {                             configuration.configure(configFile);                             sessionFactory = configuration.buildSessionFactory();                    } catch (Exception e) {                             System.err                                                .println("%%%% Error Creating SessionFactory %%%%");                             e.printStackTrace();                    }          }                public static void closeSession() throws HibernateException {         Session session = (Session) threadLocal.get();         threadLocal.set(null);           if (session != null) {             session.close();         }     }                     public static org.hibernate.SessionFactory getSessionFactory() {                    return sessionFactory;          }                     public static void setConfigFile(String configFile) {                    HibernateSessionFactory.configFile = configFile;                    sessionFactory = null;          }                     public static Configuration getConfiguration() {                    return configuration;          }                            public static void beginTransaction(){                    Transaction tx = (Transaction)txThreadLocal.get();                    if(tx == null){                             tx = getSession().beginTransaction();                             txThreadLocal.set(tx);                    }          }                            public static void commitTransaction(){                    Transaction tx = (Transaction)txThreadLocal.get();                    if(tx != null && !tx.wasCommitted() && !tx.wasRolledBack()){                             tx.commit();                             txThreadLocal.set(null);                    }          }                            public static void rollbackTransaction(){                    Transaction tx = (Transaction)txThreadLocal.get();                    txThreadLocal.set(null);                    if(tx != null && !tx.wasCommitted() && !tx.wasRolledBack()){                             tx.rollback();                    }          }   }

  2.       持久化操作類:

package org.qiujy.dao.impl;   import org.apache.log4j.Logger; import org.hibernate.HibernateException; import org.hibernate.Session; import org.qiujy.common.HibernateSessionFactory; import org.qiujy.domain.User;   public class UseDaoHBImpl {     private static Logger myLogger = Logger.getLogger(UseDaoHBImpl. class );           public void saveUser(User user) {         Session session = HibernateSessionFactory.getSession();         try {             HibernateSessionFactory.beginTransaction();               session.save(user);               HibernateSessionFactory.commitTransaction();         } catch (HibernateException e) {             HibernateSessionFactory.rollbackTransaction();             myLogger .error( " 新增使用者失敗 " , e);         } finally {             HibernateSessionFactory.closeSession();         }     }             public void removeUserByID( int id){         Session session = HibernateSessionFactory.getSession();         try {             HibernateSessionFactory.beginTransaction();                         User user = (User) session.get(User. class , new Integer(id));             session.delete(user);               HibernateSessionFactory.commitTransaction();         } catch (HibernateException e) {             HibernateSessionFactory.rollbackTransaction();             myLogger .error( " 新增使用者失敗 " , e);         } finally {             HibernateSessionFactory.closeSession();         }     }             public void updateUser(User user){         Session session = HibernateSessionFactory.getSession();         try {             HibernateSessionFactory.beginTransaction();                         session.saveOrUpdate(user);               HibernateSessionFactory.commitTransaction();         } catch (HibernateException e) {             HibernateSessionFactory.rollbackTransaction();             myLogger .error( " 新增使用者失敗 " , e);         } finally {             HibernateSessionFactory.closeSession();         }     }           public User getUserByID( int id) {         User user = null ;         Session session = HibernateSessionFactory.getSession();           try {             //get 與 load 的差別 ?             user = (User) session.get(User. class , new Integer(id));           } catch (HibernateException e) {             myLogger .error( " 查詢使用者失敗 " , e);         } finally {             HibernateSessionFactory.closeSession();         }           return user;     }       public static void main(String[] args) {           User user = new User();         user.setName( " 張三 " );         user.setAge( new Integer(26));           UseDaoHBImpl manager = new UseDaoHBImpl();         // 增         manager.saveUser(user);                 // 查         User user1 = manager.getUserByID(1);         if (user1 != null ){             user1.setName( " 李四 " );             // 改             manager.updateUser(user1);                         // 删             //manager.removeUserByID(user1.getId().intValue());         }     } }  

  3.       運作如上程式,操作成功的話,以資料庫就可以看到新插入的資料了。 4.       整個web應用程式的目錄結構如下:(我是在eclipse+MyEclispe下建構的)

hibernate3入門

5.       本例源代碼: 6.    Hibernate的核心接口: 所有的Hibernate應用中都會通路Hibernate的5個核心接口: 6.1.       Configuration接口: 此接口的執行個體用于配置并且根啟動Hibernate。Hibernate通過Cofinguration執行個體來指定對象-關系映射檔案的位置或者動态配置Hibernate的屬性,然後建立SessionFactory執行個體。 6.2.       SessionFactory接口: 一個SessionFactory執行個體對應一個資料存儲源。應用程式從SessionFactory中獲得Session執行個體。SessionFactory具有以下特點: 1.       線程安全,即同一個SessionFactory執行個體可以被應用的多個線程共享。 2.       它是重量級的,因為它需要一個很大的緩存,用來存放預定義的SQL語句以及映射中繼資料等。是以,如果應用程式隻通路一個資料庫,則隻需要建立一個SessionFactory執行個體。 6.3.       Session接口: 應用最廣泛的接口。Session也被稱為持久化管理器,它提供了和持久化相關的操作:如添加、更新、删除、加載和查詢對象。session有以下特點: 1.       線程不安全,在設計軟體架構時,應該避免多個線程共享同一個Session執行個體。 2.       Session執行個體是輕量級的,它的建立和銷毀不需要消耗太多的資源。 session有一個緩存,被稱為Hibernate的第一級緩存,它存放被目前工作單元加載的對象。 6.4.       Transaction接口: Transaction接口是Hibernate的資料庫事務接口。它對底層的事務接口做了封裝,包括: JDBC API、JTA、CORBA。 Hibernate 應用可通過一緻的Transaction接口來聲明事務邊界,這有助于應用在不同的環境和容器中移植。 6.5.       Query和Criteria接口: 它們是Hibernate的查詢接口,用于資料庫查詢對象以及控制執行查詢的過程。Query包裝了一個HQL(Hibernate Query Language)查詢語句,Criteria接口完全封裝了基于字元串形式的查詢語句,比Query更加面向對象,Cirteria接口擅長于執行動态查詢。