空間站

          北極心空

            BlogJava :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
            15 Posts :: 393 Stories :: 160 Comments :: 0 Trackbacks

          Hibernate 3 Annotations 進(jìn)階

          kjj 發(fā)表于 2007-04-09 07:39:25
          作者:kjj     來源:Onjava;Matrix
          評(píng)論數(shù):5 點(diǎn)擊數(shù):1,888     投票總得分:0 投票總?cè)舜?0
          關(guān)鍵字:Hibernate Annotations
           

          摘要:

          這些年來,Hibernate幾乎已經(jīng)成為java世界中數(shù)據(jù)庫持久化方面事實(shí)上的標(biāo)準(zhǔn),它強(qiáng)大靈活并且性能優(yōu)秀.在這篇文章中,我們來看一下Java 5的注解功能怎么簡單地用在你的hibernate代碼中讓你的持久化層變得更容易.
          這些年來,Hibernate幾乎已經(jīng)成為java世界中數(shù)據(jù)庫持久化方面事實(shí)上的標(biāo)準(zhǔn),它強(qiáng)大靈活并且性能優(yōu)秀.在這篇文章中,我們來看一下Java 5的注解功能怎么簡單地用在你的hibernate代碼中讓你的持久化層變得更容易.

          在過去,Hibernate 依靠外部的XML文件來配置持久化對(duì)象,數(shù)據(jù)庫映射文件定義在一組XML映射文件里并且在程序開始的時(shí)候被裝載.有很多辦法來創(chuàng)建這些映射文件,或者自動(dòng)從一個(gè)已存在的數(shù)據(jù)庫模式里創(chuàng)建,或者手動(dòng)從java類對(duì)象中創(chuàng)建.不管那種情況,你都得產(chǎn)生一大堆Hibernate 映射文件而結(jié)束工作.,你也可以利用外部工具從javadoc-style 的注解中生成映射文件,但這給你的開發(fā)流程增加了額外的負(fù)擔(dān).

          在最近的Hibernate版本里,一個(gè)新的建立在Java 5 注解之上更為優(yōu)雅的方法出現(xiàn)了.利用新的Hibernate Annonations 庫,你可以發(fā)布一次如你以前的映射文件所定義的信息,你猜到了-注解直接嵌入你的Java類文件里.注解帶來了一種強(qiáng)大靈活地聲明持久化映射的辦法.在最新版的幾個(gè)Java集成開發(fā)環(huán)境里都很好的支持,并帶有代碼自動(dòng)完成和語法高亮功能.

          Hibernate annotations 也支持最新的EJB 3持久化規(guī)范,這些規(guī)范目的是提供一個(gè)標(biāo)準(zhǔn)的Java持久化機(jī)制.當(dāng)然Hibernate 3也提供了更多的解決方案,你能非常容易的靠近保準(zhǔn)并且利用EJB 3編程模型編寫你的Hibernate持久化層.

          現(xiàn)在讓我們一步步了解Hibernate Annotations.


          版權(quán)聲明:任何獲得Matrix授權(quán)的網(wǎng)站,轉(zhuǎn)載時(shí)請(qǐng)務(wù)必保留以下作者信息和鏈接
          作者:kjj
          原文:http://www.matrix.org.cn/resource/article/2007-04-09/Hibernate+Annotations_62c034f4-e62a-11db-b1bd-fb5572962927.html
          關(guān)鍵字:Hibernate Annotations

          安裝 Hibernate Annotations

          為了使用Hibernate Annotations,你需要最新的Hibernate 3.2 ,當(dāng)然還有Java 5 你可以在Hibernate web site 這個(gè)網(wǎng)站下載Hibernate 3.2和Hibernate Annotations庫.除了標(biāo)準(zhǔn)的Hibernate 庫文件和必須的依賴庫之外,還需要下載 Hibernate Annotations庫和Java 持久化API ---ejb3-persstence.jar文件.如果你正在使用Maven,僅僅添加相應(yīng)的依賴到你的DOM文件里,如下所示:
           ...
              <dependency>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate</artifactId>
                <version>3.2.1.ga</version>
              </dependency>
              <dependency>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate-annotations</artifactId>
                <version>3.2.0.ga</version>
              </dependency>
              <dependency>
                <groupId>javax.persistence</groupId>
                <artifactId>persistence-api</artifactId>
                <version>1.0</version>
              </dependency>
          ...


          下一步是獲得一個(gè)Hibernate Session 工廠.利用Hibernate Annotations與不使用它創(chuàng)建Hibernate session工廠有一點(diǎn)不同,雖然不需要大幅度修改.你只需須簡單地使用AnnotationConfiguration類安裝你的session工廠:
              
          sessionFactory
          =new AnnotationConfiguration().buildSessionFactory();


          一般的,你需要通過<mapping>元素在Hibernate配置文件里(hibernate.cfg.xml)聲明持久化類
            


                  <hibernate-configuration>
                    <session-factory>
                      <mapping class="com.onjava.modelplanes.domain.PlaneType"/>
                      <mapping class="com.onjava.modelplanes.domain.ModelPlane"/>
                    </session-factory>
            </hibernate-configuration>


          如今許多java 工程都使用輕量級(jí)的程序框架例如Spring.如果你正在用Spring框架,你可以容易地利用AnnotationSessionFactory類裝配一個(gè)基于Annotations 的Hibernate Session Factory,如下:
          <!-- Hibernate session factory -->
            <bean id="sessionFactory"
                  class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
             <property name="dataSource">
               <ref bean="dataSource"/>
             </property>
             <property name="hibernateProperties">
               <props>
                 <prop key="hibernate.dialect">org.hibernate.dialect.DerbyDialect</prop>
                 <prop key="hibernate.hbm2ddl.auto">create</prop>
                 ...
               </props>
             </property>
             <property name="annotatedClasses">
               <list>
                 <value>com.onjava.modelplanes.domain.PlaneType</value>
                 <value>com.onjava.modelplanes.domain.ModelPlane</value>
                 ...
               </list>
             </property>
          </bean>


          我們第一個(gè)持久化類

          現(xiàn)在我們知道如何獲得基于Annotation的Hibernate Session ,讓我們看看這個(gè)注解的持久化類看起來像什么樣子.
          被注解的持久化類是一般的POJO類,就像在其他Hibernate程序里的一樣.好的,差不多了.你需要依賴于Java 持久化API (javax.persistence.*),并且還需要導(dǎo)入注解包類(org.hibernate.annotations.*)如果你使用了任何Hibernate擴(kuò)展的話.但是除此之外,他們僅僅是擁有持久化相關(guān)注解的POJO.這有個(gè)例子:
          @Entity
          public class ModelPlane {

              private Long id;
              private String name;
              
              @Id
              public Long getId() {
                  return id;
              }

              public void setId(Long id) {
                  this.id = id;
              }

              public String getName() {
                  return name;
              }

              public void setName(String name) {
                  this.name = name;
          }
          }


          如我們所言,非常簡單.@Entity注解聲明類將被持久化.@Id注解讓你指示持久化類的唯一性標(biāo)識(shí)屬性.實(shí)際上,你可以持久化字段(注解成員變量)或者持久化屬性(通過注釋getter方法.在這篇文章的剩余部分,我們將用基于屬性的注解.關(guān)于基于注解的持久化一個(gè)好處是他的缺省行為.例如.你不需要聲明每一個(gè)屬性是否要被持久化-任何屬性都假定將被持久化除非用@Transient注解了他. 對(duì)代碼來說這是簡單的,并且相對(duì)于舊的XML配置文件來說,也節(jié)省了很多打字量.

          生成主鍵

          Hibernate一個(gè)擅長的功能是主鍵自動(dòng)生成,Hibernate/EJB 3注解也為主鍵自動(dòng)生成提供了豐富的支持,允許諸多生成策略.下面例子演示了最常見的用途,這里Hibernate 根據(jù)數(shù)據(jù)庫給出一個(gè)合適的主鍵生成策略.
              @Id
              @GeneratedValue (strategy=GenerationType.AUTO)
              public Long getId() {
                  return id;
          }


          自定義表和字段映射
          默認(rèn)情況下,Hibernate將映射持久化類到表,用匹配的字段名映射.例如,上面的類將經(jīng)由下列SQL語句映射到表:
          CREATE TABLE MODELPLANE 
          (
              ID long,
          NAME varchar
          )


          如果你自己生成和維護(hù)數(shù)據(jù)庫的話非常好,并且使你的代碼易于維護(hù).然而,他不適合所有需求.有些程序需要訪問外部數(shù)據(jù)庫,并且可能需要公司數(shù)據(jù)庫命名轉(zhuǎn)換.如果需要的話,你可以使用@Table和@Column注解進(jìn)行你的持久化映射:
          @Entity
          @Table(name="T_MODEL_PLANE")
          public class ModelPlane {

              private Long id;
              private String name;
              
              @Id
              @Column(name="PLANE_ID")
              public Long getId() {
                  return id;
              }

              public void setId(Long id) {
                  this.id = id;
              }

              @Column(name="PLANE_NAME")
              public String getName() {
                  return name;
              }

              public void setName(String name) {
                  this.name = name;
          }
          }


          它將映射到下面的表
          CREATE TABLE T_MODEL_PLANE 
          (
              PLANE_ID long,
          PLANE_NAME varchar
          )


          你可以利用Table和Column屬性自定義映射.它可讓你指定諸如列長度,not-null約束等等,hibernate支持大量的屬性注解:
          ...
              @Column(name="PLANE_ID", length=80, nullable=true)
              public String getName() {
                  return name;
          }


          映射關(guān)系

          Java持久化映射中一個(gè)最重要,最復(fù)雜的部分是確定怎么映射表間的關(guān)系.如其他的特性一樣,Hibernate在這方面也提供了大量的靈活性,但是以增加了某種復(fù)雜度為代價(jià)的.我們將瀏覽一系列共同的用例以對(duì)如何使用注解有個(gè)大體認(rèn)識(shí).
          最常用的一個(gè)關(guān)系是many-to-one關(guān)系.假定在上面的例子中,每個(gè)ModelPlane經(jīng)由many-to-one關(guān)系被關(guān)聯(lián)到一個(gè)PlaneType (換句話說每個(gè)Model plane 被確切的關(guān)聯(lián)到一個(gè) plane type,通過給定一個(gè)plane type可以被關(guān)聯(lián)到多個(gè) model plane ),你可以映射如下:
             @ManyToOne( cascade = {CascadeType.PERSIST, CascadeType.MERGE} )
              public PlaneType getPlaneType() {
                              return planeType;
                    }


          這個(gè)CascadeType值表示Hibernate將怎么進(jìn)行級(jí)聯(lián)操作
          另外一個(gè)常用的關(guān)系是與上面相對(duì)的:one-to-many關(guān)系,也以集合而聞名,集合將映射變得有些復(fù)雜,在舊的和新的注解中,并且我們將撇開表面細(xì)節(jié)直接給你完成的例子以給你一個(gè)大概,例如在上面例子中,每一個(gè)PlaneType對(duì)象可能包含一個(gè)ModelPlane的集合,可以映射如下:

              @OneToMany(mappedBy="planeType",
                             cascade=CascadeType.ALL,
                             fetch=FetchType.EAGER)
              @OrderBy("name")
              public List<ModelPlane> getModelPlanes() {
                  return modelPlanes;
          }


          命名查詢
          Hibernate一個(gè)優(yōu)秀的特征是可以在映射文件申明命名查詢的能力.這些查詢可以通過名字在代碼里調(diào)用,這可以讓你集中查詢且避免有sql或者Hql代碼分散在程序里.

          你也可以通過注解,利用@NameQueries和@NameQuery注解,如下:

          @NamedQueries(
          {        
            @NamedQuery(
              name="planeType.findById",
              query="select p from PlaneType p left join fetch p.modelPlanes where id=:id"
            ),
            @NamedQuery(
              name="planeType.findAll",
              query="select p from PlaneType p"
            ),
            @NamedQuery(
                    name="planeType.delete",
                    query="delete from PlaneType where id=:id"
                  )  
          }
          )


          一旦定義,可以可以調(diào)用正如其他命名查詢.

          總結(jié)

          Hibernate 3注解提供了一個(gè)強(qiáng)大而優(yōu)雅的API來簡化java數(shù)據(jù)庫持久化代碼,在這里我們僅僅涉及到表面的知識(shí),你選擇貼近標(biāo)準(zhǔn),并且利用java持久化API或者收益于Hibernate的規(guī)范擴(kuò)展, 在以失去某種輕便性為代價(jià)的基礎(chǔ)上,它提供了更為強(qiáng)大靈活的功能.不管怎么樣,通過避免了xml映射文件.使用Hibernate注解可以簡化你的程序維護(hù),另外的好處是指給你一個(gè)走進(jìn)EJB 3大門的幽徑.
           
          另附:
            1 xml version="1.0" encoding="UTF-8"?>   
            2 <beans xmlns="http://www.springframework.org/schema/beans"   
            3   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
            4   xmlns:aop="http://www.springframework.org/schema/aop"   
            5   xmlns:tx="http://www.springframework.org/schema/tx"   
            6   xsi:schemaLocation="http://www.springframework.org/schema/beans   
            7         http://www.springframework.org/schema/beans/spring-beans-2.0.xsd   
            8            http://www.springframework.org/schema/aop   
            9            http://www.springframework.org/schema/aop/spring-aop-2.0.xsd   
           10                       http://www.springframework.org/schema/tx   
           11                       http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">   
           12   <!-- 定義數(shù)據(jù)庫連接的信息,如driverClass,jdbcUrl,user,password等 -->   
           13   <bean id="propertyConfigurer"   
           14         class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">   
           15     <property name="location" value="/WEB-INF/config/jdbc.properties"/>   
           16   <!--</span-->bean>   
           17   <!-- 定義數(shù)據(jù)源,該bean的ID為dataSource -->   
           18   <bean id="dataSource"   
           19         class="com.mysql.jdbc.Driver"   
           20         destroy-method="close">   
           21     <!-- 指定數(shù)據(jù)庫驅(qū)動(dòng) -->   
           22     <property name="driverClass"><value>${driverClass}<!--</span-->value><!--</span-->property>   
           23     <!-- 指定數(shù)據(jù)庫連接的URL -->   
           24     <property name="jdbcUrl"><value>${jdbcUrl}<!--</span-->value><!--</span-->property>   
           25     <!-- 指定數(shù)據(jù)庫用戶名 -->   
           26     <property name="user"><value>${user}<!--</span-->value><!--</span-->property>   
           27     <!-- 指定數(shù)據(jù)庫用戶密碼 -->   
           28     <property name="password"><value>${password}<!--</span-->value><!--</span-->property>   
           29     <property name="minPoolSize"><value>1<!--</span-->value><!--</span-->property>   
           30     <property name="maxPoolSize"><value>20<!--</span-->value><!--</span-->property>   
           31     <property name="maxIdleTime"><value>1800<!--</span-->value><!--</span-->property>   
           32     <property name="acquireIncrement"><value>2<!--</span-->value><!--</span-->property>   
           33     <property name="maxStatements"><value>0<!--</span-->value><!--</span-->property>   
           34     <property name="initialPoolSize"><value>2<!--</span-->value><!--</span-->property>   
           35     <property name="idleConnectionTestPeriod"><value>1800<!--</span-->value><!--</span-->property>   
           36     <property name="acquireRetryAttempts"><value>30<!--</span-->value><!--</span-->property>   
           37     <property name="breakAfterAcquireFailure"><value>true<!--</span-->value><!--</span-->property>   
           38     <property name="testConnectionOnCheckout"><value>false<!--</span-->value><!--</span-->property>   
           39   <!--</span-->bean>   
           40   <!-- 定義Hibernate的SessionFactory加載.hbm.xml文件時(shí)用這種配置-->   
           41   <!--<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">-->   
           42   <!-- 定義AnnotationHibernate的SessionFactory -->   
           43   <bean id="sessionFactory"   
           44         class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">   
           45     <!-- 依賴注入數(shù)據(jù)源,注入dataSource -->   
           46     <property name="dataSource" ref="dataSource" />   
           47     <!-- mappingResources屬性用來列出全部映射文件 -->   
           48     <property name="annotatedClasses">   
           49       <list>   
           50       <!-- 列出所有PO實(shí)體文件 -->   
           51         <value>com.daniel.lr.crbt.share.db.User<!--</span-->value>   
           52       <!--</span-->list>   
           53     <!--</span-->property>   
           54     <!-- 定義Hibernate的SessionFactory的屬性 -->   
           55     <property name="hibernateProperties">   
           56       <props>   
           57         <!-- 指定Hibernate的連接方言 -->   
           58         <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect<!--</span-->prop>   
           59         <!-- 不同數(shù)據(jù)庫連接,啟動(dòng)時(shí)選擇create,update,create-drop -->   
           60         <prop key="hibernate.hbm2ddl.auto">update<!--</span-->prop>   
           61         <prop key="hibernate.show_sql">true<!--</span-->prop>   
           62         <prop key="hibernate.generate_statistics">true<!--</span-->prop>   
           63         <prop key="hibernate.connection.release_mode">auto<!--</span-->prop>                        
           64         <prop key="hibernate.autoReconnect">true<!--</span-->prop>   
           65         <prop key="hibernate.bytecode.use_reflection_optimizer">true<!--</span-->prop>   
           66       <!--</span-->props>   
           67     <!--</span-->property>   
           68     <property name="eventListeners">   
           69       <map>   
           70         <entry key="merge">   
           71           <bean class="org.springframework.orm.hibernate3.support.IdTransferringMergeEventListener"/>   
           72         <!--</span-->entry>   
           73       <!--</span-->map>   
           74     <!--</span-->property>   
           75   <!--</span-->bean>   
           76   <aop:config proxy-target-class="true">   
           77     <aop:advisor pointcut="execution(* *..Hibernate.*(..))" advice-ref="txAdvice"/>   
           78   <!--</span-->aop:config>   
           79   <tx:advice id="txAdvice">   
           80     <tx:attributes>   
           81       <tx:method name="*" read-only="false"/>   
           82     <!--</span-->tx:attributes>   
           83   <!--</span-->tx:advice>   
           84   <!-- 配置Hibernate的事務(wù)管理 -->   
           85   <bean id="transactionManager"   
           86         class="org.springframework.orm.hibernate3.HibernateTransactionManager">   
           87     <property name="sessionFactory" ref="sessionFactory"/>   
           88   <!--</span-->bean>   
           89   <!-- 配置DaoBean -->   
           90   <bean id="userDao" class="com.daniel.lr.crbt.share.dao.UserDao">   
           91     <!-- 為DAO注入所需的DataSource實(shí)例 -->   
           92     <property name="sessionFactory" ref="sessionFactory"/>   
           93   <!--</span-->bean>   
           94   <!-- 配置userDao bean的事務(wù)代理 -->   
           95   <bean id="userDaoProxy"   
           96         class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">   
           97     <property name="transactionManager" ref="transactionManager" />   
           98     <property name="target" ref="userDao"/>   
           99     <property name="transactionAttributeSource">   
          100       <bean class="org.springframework.transaction.annotation.AnnotationTransactionAttributeSource"/>   
          101     <!--</span-->property>   
          102   <!--</span-->bean>   
          103   <!-- Spring代理Struts的Action Action不使用Singleton-->   
          104   <bean name="/login"   
          105         class="com.daniel.lr.crbt.service.web.action.LoginAction"   
          106         scope="prototype">   
          107     <property name="userDao" ref="userDao"/>   
          108   <!--</span-->bean>   
          109 <!--</span-->beans>   
          110 
          posted on 2007-10-08 13:21 蘆葦 閱讀(1252) 評(píng)論(2)  編輯  收藏 所屬分類: Hibernate

          Feedback

          # re: Hibernate 3 Annotations 進(jìn)階 2007-10-08 13:53 蘆葦
          在hibernate3中可以自動(dòng)建數(shù)據(jù)庫及自動(dòng)導(dǎo)入數(shù)據(jù).在hibernate.properties文件里加入:
          hibernate.hbm2ddl.auto=create
          就可以自動(dòng)建表結(jié)構(gòu)
          設(shè)hibernate.hbm2ddl.auto為update/create-drop/create其中一種都會(huì)改變表結(jié)構(gòu),如果同時(shí)在classpath中寫一個(gè)/import.sql文件,里包含了數(shù)據(jù)內(nèi)容的insert等,那么hibernate3在啟動(dòng)時(shí)就會(huì)執(zhí)行import.sql的內(nèi)容。  回復(fù)  更多評(píng)論
            

          # re: Hibernate 3 Annotations 進(jìn)階 2007-10-08 13:53 蘆葦
          WEB-INF/classes/hibernate.properties
          hibernate.hbm2ddl.auto=create
          hibernate.hbm2ddl.auto=create
          WEB-INF/classes/import.sql
          源碼復(fù)制打印
          INSERT INTO mytable(id,name) values(1,'name1');
          INSERT INTO mytable(id,name) values(2,'name2');
          INSERT INTO mytable(id,name) values(3,'name3');
          INSERT INTO mytable(id,name) values(1,'name1');
          <br/> INSERT INTO mytable(id,name) values(2,'name2');
          <br/> INSERT INTO mytable(id,name) values(3,'name3');
          當(dāng)WEB運(yùn)行時(shí),hibernate會(huì)自動(dòng)重新生成表結(jié)構(gòu)并插入import.sql里的那三條記錄.   回復(fù)  更多評(píng)論
            

          主站蜘蛛池模板: 盈江县| 武乡县| 安阳市| 武平县| 塔城市| 元氏县| 荃湾区| 岳西县| 馆陶县| 博爱县| 六盘水市| 鄯善县| 尼玛县| 金阳县| 榆社县| 玉龙| 长子县| 榆林市| 屏山县| 昌宁县| 会泽县| 明光市| 玛多县| 徐闻县| 黄山市| 汉阴县| 泰宁县| 南投市| 石首市| 丘北县| 双江| 乾安县| 罗平县| 梨树县| 威海市| 巴塘县| 水城县| 宝鸡市| 宾川县| 涟源市| 临洮县|