首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > 其他数据库 >

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

2012-10-17 
(转)扩展hibernate生成数据库的命名规则对于Java开发人员,Hibernate 3 annotations提供了非常好的方式来展

(转)扩展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

    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" + 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

热点排行