Kela's Blog

                      前面的路很坎坷,但畢竟是條路.也許走過這一段就會(huì)發(fā)現(xiàn),走過去就是夢(mèng)想中的地方.因此堅(jiān)持成為此刻唯一能做且必須去做的事情.
          posts - 9, comments - 27, trackbacks - 0, articles - 15

          一個(gè)Hibernate版本的“Hello World”

          1. 搭建環(huán)境
               建立項(xiàng)目:名稱為HibernateProject,如下圖:
               hb001.BMP
                下載Hibernate發(fā)行包:
                 這里使用 Hibernate3.X ,因?yàn)?Hibernate 在3.X 上性能有了更大的提升。(也可以采用 2. X的版本,3.X 和 2.X 之間的差異不多,這里的“不多”是從使用者的角度來看,在需要注意的地方,會(huì)注明,另附 3.X 和 2.X 差異表一張)
                下載地址:http://www.hibernate.org 在 http://www.redsaga.com 的努力之下,Hibernate 的官方發(fā)行包中( doc\reference 下),始終有高質(zhì)量的中文官方文檔,非常的感謝他們。
                在ClassPath 中設(shè)置系統(tǒng)開發(fā)需要的類庫(kù):
                在項(xiàng)目的lib目錄下添加以下類包( .jar) 文件,并且將這些 .jar 指定在系統(tǒng) ClassPath 中。(總之,無論在哪種環(huán)境中都必須保證系統(tǒng)能找到我們?cè)O(shè)置的 .jar 。
                  a.數(shù)據(jù)庫(kù)驅(qū)動(dòng)程序
                     數(shù)據(jù)庫(kù)使用 MS SQL SERVER ,以下是MS 的 JDBC 驅(qū)動(dòng)。( MS 的 JDBC 驅(qū)動(dòng)不是 Hibernate 官方的推薦驅(qū)動(dòng),在實(shí)際的項(xiàng)目中,朋友們可以根據(jù) Hibernate  開發(fā)文檔中的配置說明進(jìn)行取舍)   
                     msbase.jar,  mssqlserver.jar, msutil.jar
                  b.Hibernate 3.X 的類庫(kù)
                     將發(fā)行包下的 hibernate3.jar 文件復(fù)制到 項(xiàng)目(HibernateProject)的 lib 目錄下。
                  c.Hibernate需要的第三方類庫(kù)
                     將發(fā)行包下 lib 目錄下的 .jar 文件復(fù)制到項(xiàng)目(HibernateProject)的 lib 目錄下。
                     需要注意的是,我們這里將全部的 .jar 放在了lib中,在實(shí)際的開發(fā)中可以根據(jù)文檔配置的說明,進(jìn)行選擇。
                 
          2. 建立數(shù)據(jù)庫(kù)
              數(shù)據(jù)庫(kù)名稱:hbdb
          create database hbdb;
              數(shù)據(jù)表名稱:KELA_STUDENT  
          if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[KELA_STUDENT]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
          drop table [dbo].[KELA_STUDENT]
          GO

          CREATE TABLE [dbo].[KELA_STUDENT] (
           [StuID] [varchar] (32) COLLATE Chinese_PRC_CI_AS NOT NULL ,        -- PK
           [StuName] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,            --學(xué)生姓名
           [StuSex] [char] (1) COLLATE Chinese_PRC_CI_AS NULL ,                      --學(xué)生性別
           [StuAge] [smallint] NULL ,                                                                             --學(xué)生年齡
           [StuAddress] [varchar] (255) COLLATE Chinese_PRC_CI_AS NULL         --學(xué)生地址
          ) ON [PRIMARY]
          GO

          3. 將 發(fā)行包下 ehcache.xml 文件復(fù)制到 src 下 
              在Hibernate3中, 如果沒有這個(gè)文件會(huì)出現(xiàn)
                  WARN Configurator:126 - No configuration found. Configuring ehcache from ehcache-failsafe.xml found in
                   the classpath: jar:file:/D:/J2eeProject/HibernateProject/lib/ehcache-1.1.jar!/ehcache-failsafe.xml
                  的錯(cuò)誤。
              該文件為 Hibernate 的本身的 Cache 配置。
          4. Hibernate 配置
              Hibernate 配置文件主要用于配置數(shù)據(jù)庫(kù)連接和Hibernate運(yùn)行時(shí)所需要的各種屬性(如,連接池,SQL方言,是否現(xiàn)實(shí)SQL日志等)。
              Hibernate 同時(shí)支持 xml 格式的配置文件各傳統(tǒng)的 properties 文件配置形式,這里采用 xml 。
              配置文件名默認(rèn)為 hibernate.cfg.xml(或 hibernage.properties),Hibernate在初始化期間自動(dòng)在 classPath中尋找這個(gè)文件,并讀取其中的配置信息,并加載。
              以下是 hibernate.cfg.xml 文件(在項(xiàng)目 HibernateProject 的src 下放以下內(nèi)容):
          <?xml version="1.0" encoding="GB2312"?>
          <!DOCTYPE hibernate-configuration PUBLIC
                  "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
                  "

          <hibernate-configuration>
           <session-factory>
            
            <!-- 是否將運(yùn)行期生成的SQL輸出到日志以供調(diào)試 -->
            <property name="hibernate.show_sql">
             true
            </property>
            
            <!-- SQL 方言-->
            <property name="hibernate.dialect">
             org.hibernate.dialect.SQLServerDialect
            </property>
            
            <!-- 數(shù)據(jù)庫(kù)用戶 -->
            <property name="hibernate.connection.username">
             sa
            </property>
            
            <!-- 數(shù)據(jù)庫(kù)密碼 -->
            <property name="hibernate.connection.password">
             123456
            </property>
            
            <!-- 數(shù)據(jù)庫(kù) JDBC 驅(qū)動(dòng)-->
             <property name="hibernate.connection.driver_class">
             com.microsoft.jdbc.sqlserver.SQLServerDriver
            </property>
            
            <!-- 數(shù)據(jù)庫(kù) URL -->
            <property name="hibernate.connection.url">
             jdbc:microsoft:sqlserver://127.0.0.1:1433;DatabaseName=hbdb
            </property>
            
            <!-- 事務(wù)管理類型 -->
            <!-- Hibernate 3 對(duì)包名做了修改 ( net.sf.hibernate  => org.hibernate )-->
            <property name="hibernate.transaction.factory_class">
             org.hibernate.transaction.JDBCTransactionFactory
            </property>
            
            <!-- c3p0 連接池 -->
            <property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
            <property name="hibernate.c3p0.max_size">2</property>
            <property name="hibernate.c3p0.min_size">2</property>
            <property name="hibernate.c3p0.timeout">50000</property>
            <property name="hibernate.c3p0.max_statements">100</property>
            <property name="hibernate.c3p0.idle_test_period">3000</property>
            <property name="hibernate.c3p0.acquire_increment">2</property>
            <property name="hibernate.c3p0.validate">false</property>
           
            
            <!-- 映射的配置文件,對(duì)應(yīng)數(shù)據(jù)庫(kù)表 KELA_STUDENT 的映射文件,在后面將看到這個(gè)文件的配置 -->
            <mapping resource="com/kela/hb/pojo/KelaStudent.hbm.xml"/>
           </session-factory>
          </hibernate-configuration>

          5. 日志配置
          在Hibernate發(fā)行包的etc目錄下找到 log4j.properties 示例配置文件,可以修改其中的日志級(jí)別,也可直接使用。
          在src下,放置 log4j.properties 文件,內(nèi)容如下:
          # log4j #
          log4j.appender.stdout=org.apache.log4j.ConsoleAppender
          log4j.appender.stdout.Target=System.out
          log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
          log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

          log4j.rootLogger=warn, stdout

          #設(shè)置顯示 error以上級(jí)別log
          log4j.logger.org.hibernate=error 

          6. 構(gòu)建 POJO 類和Hibernate映射( .hbm.xml)文件
                  說明:根據(jù)數(shù)據(jù)庫(kù)定義導(dǎo)出表結(jié)構(gòu),并自動(dòng)生成對(duì)應(yīng)的映射文件和POJO java代碼,是實(shí)際開發(fā)當(dāng)中最常用的方式,也是專家所推薦的。可以使用 MiddleGen -- Hibernate,Hibernate -- Extensions 等的工具,這些工具的使用非常的方便,只修修改相應(yīng)的 ant 構(gòu)建文件即可,在網(wǎng)絡(luò)上可以很容易的找到這些工具的使用方法。
                  這里采用手工編寫 POJO 和映射文件的方法,是基于開發(fā)者更好理解 Hibernate 運(yùn)作機(jī)制而考慮。付出手工編寫會(huì)產(chǎn)生疏漏和錯(cuò)誤的代價(jià),我覺得在學(xué)習(xí)階段是值得的。
                以下是這兩個(gè)文件,他們的位置都在   com.kela.hb.pojo 下面。
          POJO類:com.kela.hb.pojo.KelaStudent
           /**
            * KelaStudent.java
            */
          package com.kela.hb.pojo;

          import java.io.Serializable;

          public class KelaStudent implements Serializable {

           private static final long serialVersionUID = 8365163573354176897L;
           
           String stuID;
           String stuName;
           String stuSex;
           Integer stuAge;
           String stuAddress;
           
           public KelaStudent() {
            
           }

           public String getStuAddress() {
            return stuAddress;
           }

           public void setStuAddress(String stuAddress) {
            this.stuAddress = stuAddress;
           }

           public Integer getStuAge() {
            return stuAge;
           }

           public void setStuAge(Integer stuAge) {
            this.stuAge = stuAge;
           }

           public String getStuID() {
            return stuID;
           }

           public void setStuID(String stuID) {
            this.stuID = stuID;
           }

           public String getStuName() {
            return stuName;
           }

           public void setStuName(String stuName) {
            this.stuName = stuName;
           }

           public String getStuSex() {
            return stuSex;
           }

           public void setStuSex(String stuSex) {
            this.stuSex = stuSex;
           }
          }

          映射文件:KelaStudent.hbm.xml
          <?xml version="1.0" encoding="GB2312"?>
          <!DOCTYPE hibernate-mapping
              PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
              "

          <hibernate-mapping>
           
           <class name="com.kela.hb.pojo.KelaStudent" table="KELA_STUDENT">
            
            <!-- id 節(jié)點(diǎn)配置了表的主鍵-->
            <id
             name="stuID"                  //POJO類指的ID
             column="StuID"              //數(shù)據(jù)庫(kù)中的主鍵名稱
             type="java.lang.String"    //字符類型
            >
              <generator class="uuid.hex"/>   //這里的uuid.hex代表了一種主鍵的生成方式
            </id>
            
             <property
                  name="stuName"       //POJO中的屬性
                column="StuName"     //屬性對(duì)應(yīng)數(shù)據(jù)庫(kù)字段的名稱
                type="java.lang.String" //屬性類型
               />
            
            <property
                name="stuSex"
                column="StuSex"
                type="java.lang.String"
               />
            
            <property
                name="stuAge"
                column="StuAge"
                type="java.lang.Integer"
               />
            
            <property
                name="stuAddress"
                column="StuAddress"
                type="java.lang.String"
               />
            
           </class>
          </hibernate-mapping>

          7. 測(cè)試代碼
          HelloTest  . java

          package com.kela.test;

          import org.hibernate.HibernateException;
          import org.hibernate.Session;
          import org.hibernate.Transaction;

          import com.kela.hb.pojo.KelaStudent;
          import com.kela.hb.util.HibernateUtil;

          public class HelloTest {

              Session session = null;
           
               public void testInsert() {

                  Transaction tran = null;

                  try {

                     //從  HibernateUtil 得到 hibernate的session,  HibernateUtil .java 文件在后
                     session = HibernateUtil.currentSession();
                     //啟動(dòng)事務(wù)
                     tran = session.beginTransaction();
             
                     KelaStudent kelaStudent = new KelaStudent();
                     //插入數(shù)據(jù)
                     kelaStudent.setStuName("王小二");
                     kelaStudent.setStuSex("T");
                     kelaStudent.setStuAge(new Integer(26));
                     kelaStudent.setStuAddress("甘肅蘭州");
                    
                     //保存并提交事務(wù)
                     session.save(kelaStudent);
                     session.flush();
                     tran.commit();
             
                  } catch (HibernateException he){
             
                     System.out.println("運(yùn)行中發(fā)生了錯(cuò)誤");
                     try {
                         HibernateUtil.closeSession();
                     } catch (HibernateException he2) {
                         System.out.println("關(guān)閉 session 沒有成功");
                     }
                  }
           
              }
           
              public static void main(String[] args) {
                  System.out.println(" ========= 開始測(cè)試 ==========");
                  HelloTest helloTest = new HelloTest();
                  helloTest.testInsert();
                  System.out.println(" ========= SUCCESS ==========");
              }

          }

          下面是 HibernateUtil  . java
          /**
           * HibernateUtil.java
           */
          package com.kela.hb.util;

          import org.apache.commons.logging.Log;
          import org.apache.commons.logging.LogFactory;
          import org.hibernate.Session;
          import org.hibernate.SessionFactory;
          import org.hibernate.cfg.Configuration;

          public class HibernateUtil {

             private static Log log = LogFactory.getLog(HibernateUtil.class);

             private static final SessionFactory sessionFactory;

             static {
                 try {
                     sessionFactory = new Configuration().configure().buildSessionFactory();
                 } catch (Throwable ex) {
                     log.error("初始化 SessionFactory 發(fā)生錯(cuò)誤.", ex);
                     throw new ExceptionInInitializerError(ex);
                 }
              }

               public static final ThreadLocal session = new ThreadLocal();

               public static Session currentSession() {
                   Session s = (Session) session.get();
                   if (s == null) {
                      s = sessionFactory.openSession();
                      session.set(s);
                  }
               return s;
              }

              public static void closeSession() {
                  Session s = (Session) session.get();
                  if (s != null)
                     s.close();
                  session.set(null);
              }

          }

          8. 運(yùn)行結(jié)果
              運(yùn)行 HelloTest.java 文件,觀察數(shù)據(jù)庫(kù)中的結(jié)果,可以看到一條數(shù)據(jù)被添加了進(jìn)來。

             數(shù)據(jù)庫(kù)結(jié)果:
             402880fc07c68f690107c68f6dfd0001          王小二         T         26         甘肅蘭州
             
             在控制臺(tái)看到如下日志:
              Hibernate:
              insert into KELA_STUDENT (StuName, StuSex, StuAge, StuAddress, StuID) values (?, ?, ?, ?, ?)
            
              就是這么神奇。不需要指定 SQL 語句一樣能實(shí)現(xiàn)SQL的功能。

          9. 關(guān)于測(cè)試代碼的解釋
              在Hibernate中session完成持久化操作,要?jiǎng)?chuàng)建一個(gè)Session實(shí)例大致需要3個(gè)步驟:
              A. 初始化Hibernate配置管理類Configuration

                   //讀入默認(rèn)的配置文件(hibernate.cfg.xml 或 hibernate.properties)來創(chuàng)建一個(gè)Configuration
                   Configuration config = new Configuration().configure();  
              B. 通過Configuration類的實(shí)例來創(chuàng)建 Session 的工廠類 SessionFactory:
                  
                   SessionFactory sessionFactory = config.buildSessionFactory();

              C. 通過SessionFactory得到Session實(shí)例:
            
                   session = sessionFactory.openSession();

              D. 通過Session實(shí)例完成持久化操作:

                     //啟動(dòng)事務(wù)
                     tran = session.beginTransaction();
             
                     KelaStudent kelaStudent = new KelaStudent();
                     //插入數(shù)據(jù)
                     kelaStudent.setStuName("王小二");
                     kelaStudent.setStuSex("T");
                     kelaStudent.setStuAge(new Integer(26));
                     kelaStudent.setStuAddress("甘肅蘭州");
                    
                     //保存并提交事務(wù)
                     session.save(kelaStudent);
                     session.flush();
                     tran.commit();

                說明:由于SessionFactory采取了線程安全的設(shè)計(jì),可以有多個(gè)線程并發(fā)調(diào)用,大多數(shù)情況下,一個(gè)應(yīng)用中針對(duì)一個(gè)數(shù)據(jù)庫(kù)共享一個(gè)SessionFactory實(shí)例即可。
                            Session(這里的Session是Hibernate的Session)可以理解成相當(dāng)于JDBC 的Connection),它的設(shè)計(jì)是非線程安全的也就是說一個(gè)Session實(shí)例只可以由一個(gè)線程使用。
                            有了以上兩點(diǎn)的考慮,在 HelloTest.java中在得到Session實(shí)例使用了:

                     //從  HibernateUtil 得到 hibernate的session,  HibernateUtil .java 文件在后
                     session = HibernateUtil.currentSession();

                    
                     在HibernateUtil.java 文件中創(chuàng)建Session,關(guān)閉Session。(這段代碼來自于Hibernate文檔)
                     這就相當(dāng)于我們平時(shí)從數(shù)據(jù)庫(kù)連接池中得到 Connection,用完了 close.conn() 是一樣的道理。

              

          Feedback

          # re: kela的筆記 ORM產(chǎn)品 ---- hibernate(3)  回復(fù)  更多評(píng)論   

          2005-11-23 16:31 by
          封裝一個(gè)hibernate的DAO調(diào)用模版,就像spring的HibernateDaoSupport一樣,這樣,代碼就會(huì)優(yōu)美很多,樓主有時(shí)間的話實(shí)現(xiàn)一個(gè)。

          # re: kela的筆記 ORM產(chǎn)品 ---- hibernate(3)  回復(fù)  更多評(píng)論   

          2005-11-23 16:33 by brother
          同樣,可以利用callback實(shí)現(xiàn)自己的aop,也建議你嘗試一下。
          分享到:
          主站蜘蛛池模板: 凤城市| 怀化市| 海城市| 保山市| 柞水县| 阳西县| 铜陵市| 巫山县| 黎城县| 梅州市| 东海县| 红安县| 南丹县| 包头市| 临清市| 高陵县| 肃宁县| 呼玛县| 克东县| 五寨县| 大石桥市| 阿城市| 沁水县| 红原县| 青田县| 大厂| 大悟县| 都昌县| 贵定县| 珠海市| 宁武县| 东源县| 大埔区| 汶上县| 南华县| 措勤县| 宝应县| 海门市| 虹口区| 宁德市| 邵武市|