`
guiqing85
  • 浏览: 168653 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

(转)扩展hibernate生成数据库的命名规则

阅读更多
对于Java开发人员,Hibernate 3 annotations提供了非常好的方式来展示域分层。你可以很轻松的通过Hibernate自动生成需要的数据库架构,带有完整的SQL脚本。然而回到现实世界,你还需要考虑到,有时数据库管理员所使用的模糊的命名惯例。本文中,“Java Power Tools”的作者John Ferguson Smart将告诉你如何通过Hibernate自动生成数据库架构,而且还方便数据库管理。

Hibernate 3 注释有一种强大的持久管理数据库的方式,运用这些注释,你不需要为XML映射文件而费心,你可以设置成默认,由系统完成,从而减少了大量需要维护的代码。Hibernate提供了强大的自动生成数据库架构的工具,因此Hibernate可以自动完成生成和更新数据库架构的操作,你也无需担心那些不可思议的SQL脚本。

第一步:更新数据库架构

用Hibernate自动更新数据库架构很容易,你所需要做的只是设置好Hibernate.hbm2ddl.auto,如示例1:

示例1:

<hibernate-configuration>  

      <session-factory>            

          <property name="hibernate.dialect">

              org.hibernate.dialect.Oracle10gDialect

          </property>     

          <property name="hibernate.hbm2ddl.auto">

               create-drop

          </property>     

            ...     

          <!-- Persistent classes -->     

          <mapping class="com.mycompany.myapp.domain.Client"/>     

          <mapping class="com.mycompany.myapp.domain.Order"/>     

           ...  

      </session-factory>  

</hibernate-configuration>


设置它的属性为“create-drop”,那么每次启动应用程序都会产生新的数据库,这对集成测试很有用,但是有些情况下却不需要。另一方面,如果你设置这个值是为了更新,如果不存在数据库,Hibernate只会自动创建数据库,并更新与当前域模型匹配的所有表。

现在,在默认情况下,Hibernate将创建一套与Java类很相似的表及字段,从Java开发者的角度来看这样刚好符合要求。考虑下面的例子:

示例2:A simple persistent class

@Entitypublic class Client implements Serializable {   

     @Id   

     @GeneratedValue(strategy = GenerationType.AUTO)   

     private Long id;   

     private String firstName;   

     private String lastName;   

     ...

}

这个类中,Hibernate在默认情况下创建SQL模式,可以继续看示例3。

示例3:


create table Client (       

     id bigint generated by default as identity (start with 1),       

     firstName varchar(255),       

     lastName varchar(255),       

     ...       

     primary key (id)   

);


旧的命名惯例

数据库的惯例约定有相当充分的理由存在,但是在任何情况下DBA常常要保守一些。开发者该如何做呢?

一个简单的解决办法是使用名字特征:@Entity、@Column注释,这种方法优于默认情况下,如示例4:

示例4:

@Entity(name="T_CLIENT")

public class Client implements Serializable {

    ...

    @Id

    @GeneratedValue(strategy = GenerationType.AUTO)

    @Column(name="CLIENT_ID")

    private Long id;

    @Column(name="FIRST_NAME")

    private String firstName;

    @Column(name="LAST_NAME")

    private String lastName;

    ...

}

这样很有作用,但是会有些麻烦,你不得不有更多的表。实际上,你必须对每个表及字段都做这样的操作。有没有更好的方法呢?当然,你可以在Hibernate会话中定义命名策略集合取代默认值。这样的话你得写一个类,说明Hibernate如何定义表及字段名。从ImprovedNamingStrategy类开始是一个恰当位置,用下划线转换类名,如SomeDomainEntity,转换成some_domain_entity。在启动Hibernate会话时需准备这个类。如果你用Spring,需简化创建命名策略bean并为命名策略集合提供所创建的命名策略。示例5就是Spring配置的典型说明:

示例5:

<bean id="sessionFactory"

    class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">      

       <property name="dataSource" ref="dataSource" />

       <property name="configLocation" value="classpath:/hibernate.cfg.xml" />

       <property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" />

       <property name="namingStrategy" ref="namingStrategy" />

</bean>

<bean id="namingStrategy" class="org.hibernate.cfg.ImprovedNamingStrategy"/>

在这种命名策略下,Hibernate将生成如下面示例6的脚本:

示例6:

create table client (

       id bigint generated by default as identity (start with 1),

       first_name varchar(255),

       last_name varchar(255),

       ...

       primary key (id)   

);

这样虽然很好,但是它不能解决你所的问题。还需要数据库命名约定。例如,每个表都可能从“T_”开始(比如T_CLIENT就是Client类),或者表中的每个字段可能以表中特定的前缀开始(比如写成CLI_FIRST_NAME和CLI_LAST_NAME)。为了能自动生成这些约束,你写自己的命名策略实施。自定义命名策略实现自定义命名策略最简单的方法是扩展ImprovedNamingStrategy类。这个类提供一些用户默认的情况,因此你只需实现你真正需要的方法就可以。你可以不去理睬通用样式任务的表名和列名方法,比如,把名称都加上大写字母。Hibernate生成表或列名时就会调用这种方法,甚至是在注释中明确指定的列名也会调用这种方法。,从ImprovedNamingStrategy类继承而来的addUnderscores()方法,可以派上用场,如示例7所示:

示例7:

public class MyNamingStrategy extends ImprovedNamingStrategy implements NamingStrategy {

    @Override

    public String columnName(String columnName) {

        return addUnderscores(columnName).toUpperCase();

    }

    @Override

    public String tableName(String tableName) {

        return addUnderscores(tableName).toUpperCase();

    }

}

接下来的示例8,展现的是如何在表名前加“T_”前缀,转换成名字前加大写字母和下划线。

示例8:

    @Override

    public String classToTableName(String className) {

        return "T_" + tableName(className);

    }

    @Override

    public String propertyToColumnName(String propertyName) {

        return addUnderscores(propertyName).toUpperCase();

    }

一个更复杂的命名策略命名策略接口实际上非常简单,但在很多方面受限制。首先,在任何特定的时间你无法知道调用方法的参数是属于哪个表。这样会受限制,比如,如果需要在表中每个列名前加表前缀,正如数据库约定所要求的。可以在classToTableName()方法中加变量成员存储当前的表,来解决这个限制。对于给定的表,这个方法将在propertyToColunmName()方法后被调用。例如,示例9为表创建了三个字母的前缀,加在表名及表中所有列名前。

示例9:

public class MyNamingStrategy extends ImprovedNamingStrategy implements NamingStrategy {

    private String currentTablePrefix;

    @Override

    public String classToTableName(String className) {

        currentTablePrefix = className.substring(0, 3).toUpperCase() + "_"$$

        return "T" + currentTablePrefix + tableName(className);

    }

    @Override

    public String propertyToColumnName(String propertyName) {

        return currentTablePrefix + addUnderscores(propertyName).toUpperCase();

    }

    @Override

    public String columnName(String columnName) {

        return addUnderscores(columnName).toUpperCase();

    }

    @Override

    public String tableName(String tableName) {

        return addUnderscores(tableName).toUpperCase();

    }

}

使用这种命名策略,Hibernate将产生如示例10的代码:

示例10:

create table TCLI_CLIENT (

        CLI_ID bigint generated by default as identity (start with 1),

        CLI_FIRST_NAME varchar(255),

        CLI_LAST_NAME varchar(255),

        ...

        primary key (CLI_ID)

);

外部关键字一般很难自动生成的外部关键字,构成了一个麻烦的问题。默认情况下,Hibernate可随机生成如“FKAB1273D65CCF7AB”这样的名字,DBA不会喜欢这样自动产生的命名。解决这个问题,需要使用@ForeignKey注释,如示例11所示:

示例11:

    @Entity

    public class Order {

        ...

       @JoinColumn(name = "CLIENT_ID")

       @ManyToOne(optional = false)

       @ForeignKey(name = "FK_CLIENT_ORDERS")

       private Client client;

       ...

    }

多对多关系当然,复杂的关系下(比如多对多的关系),上面所说的变得有些更复杂。例如,示例12中的SocialNerworker类,有许多朋友。这种情况下,你需要使用像@JoinTable,@ForeignKey这样的注释。

示例12:

    @Entity

    public class SocialNetworker {

        @ManyToMany

        @JoinTable(name = "TFRD_FRIEND",

                   joinColumns = {@JoinColumn(name = "NETWORKER_ID") },

                   inverseJoinColumns = {@JoinColumn(name = "FRIEND_ID") }

         )

        @ForeignKey(name = "FK_SNT_FRIENDS",

                     inverseName="FK_FRD_FRIENDS")

          }

        private Set<SocialNetworker> friends = new HashSet<SocialNetworker>();

        ...

    }

展示SQL脚本一旦你需要对数据库做改动或更新时,数据库管理员出于职责会很谨慎,可能会看要执行的SQL脚本,Hibernate可以通过SchemaExport工具,展示SQL脚本。你使用这个工具把要完成的模式生成普通的SQL脚本。当然,此类操作你不想做为构建过程的一部分去做,如果使用Maven,例如,你使用Hibernate3-maven-plugin自动生成数据库架构。关键部分如示例13所示,当然你可以设置drop和export为false,这样就相当于没有更新数据库资料。

示例13:

<plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>hibernate3-maven-plugin</artifactId>
                <version>2.1</version>
                <executions>
                    <execution>
                        <phase>process-classes</phase>
                        <goals>
                            <goal>hbm2ddl</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <components>
                        <component>
                            <name>hbm2ddl</name>
                            <implementation>annotationconfiguration</implementation>
                        </component>
                        <component>
                            <name>hbmdoc</name>
                        </component>
                    </components>
                    <componentProperties>
                        <configurationfile>/target/classes/hibernate.cfg.xml</configurationfile>
                        <outputfilename>schema.ddl</outputfilename>
                        <namingstrategy>mycompany.myapp.IRDNamingStrategy</namingstrategy>
                        <drop>false</drop>
                        <create>true</create>
                        <export>false</export>
                        <format>true</format>
                    </componentProperties>
                </configuration>
            </plugin>

这样会生成SQL脚本,可以拿给DBA们看了。总结DBA命名惯例保留了下来,如果你将与他们共事,将需要顾及这些惯例。幸运的是,这并不意味着你要放弃Hibernate自动产生的数据库架构,也不用自已写SQL脚本。用相结合的命名策略,你会获得双赢。
原文地址:http://www.yeeyan.com/articles/view/38467/12438
分享到:
评论
1 楼 yzhw 2011-01-05  
从数据库生成实体时可能会遇到这样的问题,描述太长了,发个连接,里面有很详细的讲解
http://www.360doc.com/content/08/1231/15/94066_2235043.shtml

相关推荐

    根据数据库表生成实体、hibernate配置文件和实体映射文件

    3. 指定生成文件的位置和命名规则。 4. 运行代码生成工具,它会基于数据库表结构创建实体类、配置文件和映射文件。 5. 在生成的文件中进行必要的调整,例如添加业务逻辑、验证规则等。 通过这个过程,开发者可以...

    eclipse插件,根据数据库表自动生成DTO(pojo)插件

    JavaBean是一种特定的Java类,遵循特定的命名和设计规则,通常用于数据封装。生成的DTO和POJO类可能符合JavaBean规范,方便在各种Java应用中使用。 在压缩包中,`plugin.xml`文件是Eclipse插件的核心配置文件,它...

    hibernate实体生成工具

    - **可定制化**:多数实体生成工具允许用户自定义生成模板,比如字段命名规则、注释等。 - **兼容性**:工具通常支持多种数据库,如MySQL、Oracle、PostgreSQL等。 - **版本控制**:随着数据库表结构的修改,工具也...

    hibernate的映射表生成器

    4. **映射文件(hbm.xml)**: Hibernate使用XML文件(通常命名为.hbm.xml)来定义实体类与数据库表之间的映射。映射文件包含了类名、表名、属性到列的映射、主键设置等详细信息。这个“映射表生成器”工具可以帮助...

    通过Hibernate Tool 来生成Java类和HBM文件

    在这个文件中,你可以指定哪些数据库表需要被映射为Java类,以及这些类的命名规则。例如,你可以设置是否生成对应的setter和getter方法,或者是否使用特定的命名策略。 完成上述步骤后,就可以使用Hibernate Tool来...

    hibernate-extensions和Middlegen-Hibernate

    Middlegen-Hibernate的强大之处在于其灵活性,可以通过配置文件定制生成的代码风格和命名规则。 使用hibernate-extensions和Middlegen-Hibernate,开发者可以快速搭建起基于Hibernate的项目,大大缩短项目的启动...

    hibernate 配置 实体生成

    - 在弹出的对话框中,指定生成实体类的目标位置和命名规则,点击确定后,IDE会自动根据表结构生成对应的实体类。 4. 实体生成的扩展: - `hibernate.reveng.xml`:除了图形界面生成,也可以通过配置此文件来生成...

    HIBERNATE - 符合Java习惯的关系数据库持久化

    6. **对象/关系数据库映射基础**:深入介绍了映射定义,包括doctype、hibernate-mapping、class、id(包括不同的标识生成策略,如Hi/Lo算法、UUID算法、序列等)、composite-id、discriminator和version等元素,这些...

    自动读取mysql数据库字段并自动生成java属性和set和get方法

    在实际应用中,这也可以扩展到其他ORM(对象关系映射)框架,如Hibernate或MyBatis,它们同样依赖于数据库字段和Java对象的映射。 在压缩包子文件的文件名称列表中,"FieldToRead--属性读写"可能表示的是一个实现此...

    数据库实体类代码生成

    数据库实体类代码生成是一种常见的开发辅助工具,它能够自动生成对应数据库表结构的Java对象(实体类),大大节省了开发人员手动编写这些类的时间。在Java Web开发中,特别是使用ORM(Object-Relational Mapping)...

    MyEclipse中配置Hibernate

    ### MyEclipse中配置Hibernate连接Oracle详解 #### 一、概述 ...这种配置方式不仅简化了数据库访问的复杂性,还提高了代码的可维护性和扩展性。希望本文能帮助到正在学习和使用Hibernate技术的开发者们。

    Hibernate_3.2.0_符合Java习惯的关系数据库持久化

    HIBERNATE - 符合Java习惯的关系数据库持久化 Hibernate参考文档 3.2 -------------------------------------------------------------------------------- 目录 前言 1. 翻译说明 2. 版权声明 1. Hibernate...

    Hibernate Tools的使用,Eclipse逆向工程

    此外,还可以自定义生成的实体类名和属性命名规则。 5. **生成实体类和映射文件**:完成上述设置后,点击"Finish",Eclipse会自动根据选定的表生成相应的Java实体类和`.hbm.xml`映射文件。 **四、使用生成的实体类...

    hibernate学习笔记文档

    - 实体类设计时应遵循一定的命名规则,并确保实体类中存在类似于主键的字段,以便与数据库表中的主键进行映射。 - 使用 XML 文件(如 `User.hbm.xml`)来定义实体类与数据库表之间的映射关系。 #### 三、...

    eclipse 下的hibernate tools

    这个工具集使得开发者能够更方便地进行Hibernate对象关系映射(ORM)框架的开发工作,包括模型类的生成、HQL查询的编写和测试、数据库逆向工程等。以下是关于Hibernate Tools的详细知识点: 1. **Hibernate ORM框架...

    java 里 自动生成 dao 工具的代码

    综上所述,"java 里 自动生成 DAO 工具的代码"是为了提升Java Web开发效率而设计的,它结合了ORM框架,如Hibernate和MyBatis,能根据数据库模式自动生成DAO层代码,使开发者可以更专注于业务逻辑。在实际项目中,...

    Hibernate2.1.2参考手册中文版

    2. **实体类与映射文件**: Hibernate通过XML映射文件(*.hbm.xml)来定义Java类和数据库表的关系,包括字段映射、主键生成策略等。此外,自Hibernate 3.0起,还可以使用注解方式进行映射,使得代码更加简洁。 3. **...

    hibernate中文文档

    - **实现NamingStrategy**:自定义命名策略来处理Hibernate生成的SQL语句中的表名和列名。 - **XML配置文件**:详细说明如何使用XML文件来配置Hibernate的各种设置。 - **J2EE应用程序服务器的集成**:探讨如何将...

    Hibernate3实战 MyEclipse ,最新PPT教程

    DAO类通常包含与特定数据表相关的一系列操作,如添加、修改、删除和查询,以表名+DAO为命名规则。在本教程中,DAO类的生成减轻了开发者的负担,使他们能更专注于业务逻辑的实现。 总结,通过MyEclipse的Hibernate3...

Global site tag (gtag.js) - Google Analytics