空间站

北极心空

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  15 Posts :: 393 Stories :: 160 Comments :: 0 Trackbacks

Hibernate 3 Annotations 进阶

kjj 发表于 2007-04-09 07:39:25
作者:kjj     来源:Onjava;Matrix
评论数:5 点击数:1,888     投票总得分:0 投票总人次:0
关键字:Hibernate Annotations
 

摘要:

这些年来,Hibernate几乎已经成为java世界中数据库持久化方面事实上的标准,它强大灵活并且性能优秀.在这篇文章中,我们来看一下Java 5的注解功能怎么简单地用在你的hibernate代码中让你的持久化层变得更容易.
这些年来,Hibernate几乎已经成为java世界中数据库持久化方面事实上的标准,它强大灵活并且性能优秀.在这篇文章中,我们来看一下Java 5的注解功能怎么简单地用在你的hibernate代码中让你的持久化层变得更容易.

在过去,Hibernate 依靠外部的XML文件来配置持久化对象,数据库映射文件定义在一组XML映射文件里并且在程序开始的时候被装载.有很多办法来创建这些映射文件,或者自动从一个已存在的数据库模式里创建,或者手动从java类对象中创建.不管那种情况,你都得产生一大堆Hibernate 映射文件而结束工作.,你也可以利用外部工具从javadoc-style 的注解中生成映射文件,但这给你的开发流程增加了额外的负担.

在最近的Hibernate版本里,一个新的建立在Java 5 注解之上更为优雅的方法出现了.利用新的Hibernate Annonations 库,你可以发布一次如你以前的映射文件所定义的信息,你猜到了-注解直接嵌入你的Java类文件里.注解带来了一种强大灵活地声明持久化映射的办法.在最新版的几个Java集成开发环境里都很好的支持,并带有代码自动完成和语法高亮功能.

Hibernate annotations 也支持最新的EJB 3持久化规范,这些规范目的是提供一个标准的Java持久化机制.当然Hibernate 3也提供了更多的解决方案,你能非常容易的靠近保准并且利用EJB 3编程模型编写你的Hibernate持久化层.

现在让我们一步步了解Hibernate Annotations.


版权声明:任何获得Matrix授权的网站,转载时请务必保留以下作者信息和链接
作者:kjj
原文:http://www.matrix.org.cn/resource/article/2007-04-09/Hibernate+Annotations_62c034f4-e62a-11db-b1bd-fb5572962927.html
关键字:Hibernate Annotations

安装 Hibernate Annotations

为了使用Hibernate Annotations,你需要最新的Hibernate 3.2 ,当然还有Java 5 你可以在Hibernate web site 这个网站下载Hibernate 3.2和Hibernate Annotations库.除了标准的Hibernate 库文件和必须的依赖库之外,还需要下载 Hibernate Annotations库和Java 持久化API ---ejb3-persstence.jar文件.如果你正在使用Maven,仅仅添加相应的依赖到你的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>
...


下一步是获得一个Hibernate Session 工厂.利用Hibernate Annotations与不使用它创建Hibernate session工厂有一点不同,虽然不需要大幅度修改.你只需须简单地使用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 工程都使用轻量级的程序框架例如Spring.如果你正在用Spring框架,你可以容易地利用AnnotationSessionFactory类装配一个基于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>


我们第一个持久化类

现在我们知道如何获得基于Annotation的Hibernate Session ,让我们看看这个注解的持久化类看起来像什么样子.
被注解的持久化类是一般的POJO类,就像在其他Hibernate程序里的一样.好的,差不多了.你需要依赖于Java 持久化API (javax.persistence.*),并且还需要导入注解包类(org.hibernate.annotations.*)如果你使用了任何Hibernate扩展的话.但是除此之外,他们仅仅是拥有持久化相关注解的POJO.这有个例子:
@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注解让你指示持久化类的唯一性标识属性.实际上,你可以持久化字段(注解成员变量)或者持久化属性(通过注释getter方法.在这篇文章的剩余部分,我们将用基于属性的注解.关于基于注解的持久化一个好处是他的缺省行为.例如.你不需要声明每一个属性是否要被持久化-任何属性都假定将被持久化除非用@Transient注解了他. 对代码来说这是简单的,并且相对于旧的XML配置文件来说,也节省了很多打字量.

生成主键

Hibernate一个擅长的功能是主键自动生成,Hibernate/EJB 3注解也为主键自动生成提供了丰富的支持,允许诸多生成策略.下面例子演示了最常见的用途,这里Hibernate 根据数据库给出一个合适的主键生成策略.
    @Id
    @GeneratedValue (strategy=GenerationType.AUTO)
    public Long getId() {
        return id;
}


自定义表和字段映射
默认情况下,Hibernate将映射持久化类到表,用匹配的字段名映射.例如,上面的类将经由下列SQL语句映射到表:
CREATE TABLE MODELPLANE 
(
    ID long,
NAME varchar
)


如果你自己生成和维护数据库的话非常好,并且使你的代码易于维护.然而,他不适合所有需求.有些程序需要访问外部数据库,并且可能需要公司数据库命名转换.如果需要的话,你可以使用@Table和@Column注解进行你的持久化映射:
@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;
}


映射关系

Java持久化映射中一个最重要,最复杂的部分是确定怎么映射表间的关系.如其他的特性一样,Hibernate在这方面也提供了大量的灵活性,但是以增加了某种复杂度为代价的.我们将浏览一系列共同的用例以对如何使用注解有个大体认识.
最常用的一个关系是many-to-one关系.假定在上面的例子中,每个ModelPlane经由many-to-one关系被关联到一个PlaneType (换句话说每个Model plane 被确切的关联到一个 plane type,通过给定一个plane type可以被关联到多个 model plane ),你可以映射如下:
   @ManyToOne( cascade = {CascadeType.PERSIST, CascadeType.MERGE} )
    public PlaneType getPlaneType() {
                    return planeType;
          }


这个CascadeType值表示Hibernate将怎么进行级联操作
另外一个常用的关系是与上面相对的:one-to-many关系,也以集合而闻名,集合将映射变得有些复杂,在旧的和新的注解中,并且我们将撇开表面细节直接给你完成的例子以给你一个大概,例如在上面例子中,每一个PlaneType对象可能包含一个ModelPlane的集合,可以映射如下:

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


命名查询
Hibernate一个优秀的特征是可以在映射文件申明命名查询的能力.这些查询可以通过名字在代码里调用,这可以让你集中查询且避免有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"
        )  
}
)


一旦定义,可以可以调用正如其他命名查询.

总结

Hibernate 3注解提供了一个强大而优雅的API来简化java数据库持久化代码,在这里我们仅仅涉及到表面的知识,你选择贴近标准,并且利用java持久化API或者收益于Hibernate的规范扩展, 在以失去某种轻便性为代价的基础上,它提供了更为强大灵活的功能.不管怎么样,通过避免了xml映射文件.使用Hibernate注解可以简化你的程序维护,另外的好处是指给你一个走进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   <!-- 定义数据库连接的信息,如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   <!-- 定义数据源,该bean的ID为dataSource -->   
 18   <bean id="dataSource"   
 19         class="com.mysql.jdbc.Driver"   
 20         destroy-method="close">   
 21     <!-- 指定数据库驱动 -->   
 22     <property name="driverClass"><value>${driverClass}<!--</span-->value><!--</span-->property>   
 23     <!-- 指定数据库连接的URL -->   
 24     <property name="jdbcUrl"><value>${jdbcUrl}<!--</span-->value><!--</span-->property>   
 25     <!-- 指定数据库用户名 -->   
 26     <property name="user"><value>${user}<!--</span-->value><!--</span-->property>   
 27     <!-- 指定数据库用户密码 -->   
 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文件时用这种配置-->   
 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     <!-- 依赖注入数据源,注入dataSource -->   
 46     <property name="dataSource" ref="dataSource" />   
 47     <!-- mappingResources属性用来列出全部映射文件 -->   
 48     <property name="annotatedClasses">   
 49       <list>   
 50       <!-- 列出所有PO实体文件 -->   
 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         <!-- 不同数据库连接,启动时选择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的事务管理 -->   
 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实例 -->   
 92     <property name="sessionFactory" ref="sessionFactory"/>   
 93   <!--</span-->bean>   
 94   <!-- 配置userDao bean的事务代理 -->   
 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 芦苇 阅读(1219) 评论(2)  编辑  收藏 所属分类: Hibernate

Feedback

# re: Hibernate 3 Annotations 进阶 2007-10-08 13:53 芦苇
在hibernate3中可以自动建数据库及自动导入数据.在hibernate.properties文件里加入:
hibernate.hbm2ddl.auto=create
就可以自动建表结构
设hibernate.hbm2ddl.auto为update/create-drop/create其中一种都会改变表结构,如果同时在classpath中写一个/import.sql文件,里包含了数据内容的insert等,那么hibernate3在启动时就会执行import.sql的内容。  回复  更多评论
  

# re: Hibernate 3 Annotations 进阶 2007-10-08 13:53 芦苇
WEB-INF/classes/hibernate.properties
hibernate.hbm2ddl.auto=create
hibernate.hbm2ddl.auto=create
WEB-INF/classes/import.sql
源码复制打印
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');
当WEB运行时,hibernate会自动重新生成表结构并插入import.sql里的那三条记录.   回复  更多评论
  


只有注册用户登录后才能发表评论。


网站导航: