`

修改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

@Entity
public 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们看了。

分享到:
评论

相关推荐

    Hibernate 3.2反向生成数据库文件

    在反向生成数据库文件的过程中,首先你需要确保已安装并配置好Hibernate 3.2以及相应的JDBC驱动(对于SQL 2000,这通常是Microsoft的JDBC驱动)。接下来,按照以下步骤进行操作: 1. **配置Hibernate**: 创建...

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

    本教程将深入讲解如何根据数据库表自动生成实体类、Hibernate配置文件以及实体映射文件。 首先,我们需要了解Hibernate的基本概念。Hibernate提供了一个在Java应用中使用的持久化模型,它允许开发者用面向对象的...

    hibernate实体生成工具

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

    Hibernate自动生成配置文件

    本篇文章将详细讲解如何在MyEclipse环境下使用Hibernate连接数据库并自动生成配置文件。 首先,我们需要创建一个Web工程。在MyEclipse中,可以通过菜单栏选择“File” -&gt; “New” -&gt; “Dynamic Web Project”,为...

    hibernate生成pojo

    ### Hibernate生成POJO详解 #### 一、简介 在Java开发中,Hibernate作为一个流行的ORM(Object Relational Mapping)框架,极大地简化了数据持久化的复杂度。通过Hibernate,开发者可以将对象模型映射到关系型...

    数据库表生成javabean工具及源代码(修正版)

    数据库表生成JavaBean工具是一种非常实用的开发辅助工具,它能极大地提高开发效率,尤其是在处理大量数据模型对象时。此工具允许开发者连接到数据库,自动获取数据库中的表结构,并将其转换为符合Java Bean规范的类...

    hibernate的映射表生成器

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

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

    生成的Java类通常是每个数据库表对应一个,它们包含了与表字段相对应的属性,以及由Hibernate生成的getter和setter方法。HBM文件则是XML格式,它描述了Java类与数据库表之间的映射关系,包括字段类型、主键、外键等...

    如何使用Hibernate Tools生成Entity Bean

    为了简化开发过程,Hibernate提供了一款名为Hibernate Tools的插件,该插件可以集成到Eclipse、IntelliJ IDEA等IDE中,帮助我们自动生成Entity Bean,也就是Java对象,这些对象与数据库表进行映射。本篇将详细讲解...

    Myeclipse生成Hibernate映射文件

    在IT行业中,开发Java应用程序时,常常需要使用到ORM(对象关系映射)框架,比如Hibernate,它能够帮助我们把数据库中的数据与Java对象进行映射,从而简化数据操作。而MyEclipse作为一款强大的Java集成开发环境,...

    根据数据库生成实体类的一个工具

    这可能包括字段的命名规则、是否生成equals()和hashCode()方法、是否添加序列化注解`@Serializable`,甚至是否启用Lombok库来简化getter和setter的生成。模板配置的灵活性确保了代码风格的一致性,同时也满足了不同...

    bean对象生成数据表

    生成数据库表的过程通常涉及以下步骤: 1. **分析Bean类**:首先,你需要有一组已经定义好的Bean类,这些类的属性对应你想要在数据库中创建的列。例如,一个名为`User`的Bean类可能有`id`、`name`和`email`等属性。...

    数据库的类生成器

    如果是配置文件,里面可能包含数据库连接信息、生成选项等,用户可以根据自己的项目进行修改。 总的来说,数据库的类生成器是一个非常实用的开发工具,它可以帮助开发者快速构建与数据库表对应的实体类,减少手动...

    代码自动生成工具 hibernate配置文件工具 MagicalTools

    例如,可以在生成的DAO类中添加自定义的方法,或者调整实体类的命名规则。 此外,MagicalTools不仅仅是一个代码生成工具,它还可以帮助进行数据库管理,如查看数据库结构、执行SQL语句,甚至进行数据导入导出,为...

    hibernate-extensions和Middlegen-Hibernate

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

    java根据数据库自动生成vo 类

    - 命名规范:生成的VO类名通常遵循驼峰命名法,字段名则根据数据库列名转换,如`column_name`转换为`columnName`。 - 注解使用:现代Java开发倾向于使用注解来提供额外的信息,例如,`@Entity`(Hibernate)、`@...

    hibernate 配置 实体生成

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

Global site tag (gtag.js) - Google Analytics