Java 从 JPA 注释的实体类自动生成数据模式

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/297438/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 12:44:16  来源:igfitidea点击:

Auto generate data schema from JPA annotated entity classes

javadatabasehibernatejpajakarta-ee

提问by Steve Kuo

I'm using JPA (Hibernate's implementation) to annotate entity classes to persist to a relational database (MySQL or SQL Server). Is there an easy way to auto generate the database schema (table creation scripts) from the annotated classes?

我正在使用 JPA(Hibernate 的实现)来注释实体类以持久化到关系数据库(MySQL 或 SQL Server)。有没有一种简单的方法可以从带注释的类自动生成数据库模式(表创建脚本)?

I'm still in the prototyping phase and anticipate frequent schema changes. I would like to be able to specify and change the data model from the annotated code. Grails is similar in that it generates the database from the domain classes.

我仍处于原型设计阶段,预计架构会频繁更改。我希望能够从带注释的代码中指定和更改数据模型。Grails 的相似之处在于它从域类生成数据库。

采纳答案by Vincent Ramdhanie

You can use hbm2ddlfrom Hibernate. The docs are here.

您可以使用Hibernate 中的hbm2ddl。文档在这里

回答by hohonuuli

As a related note: Documentation for generating database schemas using EclipseLink JPA can be found here.

作为相关说明:可以在此处找到使用 EclipseLink JPA 生成数据库模式的文档。

回答by H2000

Generate create and drop script for given JPA entities

为给定的 JPA 实体生成创建和删除脚本

We use this code to generate the drop and create statements: Just construct this class with all entity classes and call create/dropTableScript.

我们使用此代码生成 drop 和 create 语句:只需使用所有实体类构建此类并调用 create/dropTableScript。

If needed you can use a persitence.xml and persitance unit name instead. Just say something and I post the code too.

如果需要,您可以改用 persitence.xml 和持久性单元名称。随便说点什么,我也贴出代码。

import java.util.Collection;
import java.util.Properties;

import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.dialect.Dialect;
import org.hibernate.ejb.Ejb3Configuration;

/**
 * SQL Creator for Tables according to JPA/Hibernate annotations.
 *
 * Use:
 *
 * {@link #createTablesScript()} To create the table creationg script
 *
 * {@link #dropTablesScript()} to create the table destruction script
 * 
 */
public class SqlTableCreator {

    private final AnnotationConfiguration hibernateConfiguration;
    private final Properties dialectProps;

    public SqlTableCreator(final Collection<Class<?>> entities) {

        final Ejb3Configuration ejb3Configuration = new Ejb3Configuration();
        for (final Class<?> entity : entities) {
            ejb3Configuration.addAnnotatedClass(entity);
        }

        dialectProps = new Properties();
        dialectProps.put("hibernate.dialect", "org.hibernate.dialect.SQLServerDialect");

        hibernateConfiguration = ejb3Configuration.getHibernateConfiguration();
    }

    /**
     * Create the SQL script to create all tables.
     * 
     * @return A {@link String} representing the SQL script.
     */
    public String createTablesScript() {
        final StringBuilder script = new StringBuilder();

        final String[] creationScript = hibernateConfiguration.generateSchemaCreationScript(Dialect
                .getDialect(dialectProps));
        for (final String string : creationScript) {
            script.append(string).append(";\n");
        }
        script.append("\ngo\n\n");

        return script.toString();
    }

    /**
     * Create the SQL script to drop all tables.
     * 
     * @return A {@link String} representing the SQL script.
     */
    public String dropTablesScript() {
        final StringBuilder script = new StringBuilder();

        final String[] creationScript = hibernateConfiguration.generateDropSchemaScript(Dialect
                .getDialect(dialectProps));
        for (final String string : creationScript) {
            script.append(string).append(";\n");
        }
        script.append("\ngo\n\n");

        return script.toString();
    }
}

回答by Andrew Thompson

Here's an explaination of how to use the hibernate SchemaExport class to do exactly what you want.

这里解释了如何使用 hibernate SchemaExport 类来做你想做的事情。

http://jandrewthompson.blogspot.com/2009/10/how-to-generate-ddl-scripts-from.html

http://jandrewthompson.blogspot.com/2009/10/how-to-generate-ddl-scripts-from.html

回答by George Papatheodorou

If you prefer configuring in Spring then this should be helpful:

如果您更喜欢在 Spring 中进行配置,那么这应该会有所帮助:

 <!-- CONTAINER-MANAGED JPA Entity manager factory (No need for persistence.xml)-->
    <bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>
    <!-- Fine Grained JPA properties Create-Drop Records -->
    <property name="jpaProperties">
    <props>
    <prop key="hibernate.hbm2ddl.auto">create</prop>
    </props>
    </property> 
    </bean> 
     <!-- The JPA vendor -->
    <bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
    <!-- <property name="database" value="MySQL"/> -->
    <property name="showSql" value="true"/>
    <!--  <property name="generateDdl" value="true"/>  -->
    <property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect"/>      
    </bean> 
     <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="emf" />
     </bean>

回答by sendon1982

You can use maven plugin to achieve this.

您可以使用 maven 插件来实现这一点。

       <plugin>
            <!-- run command "mvn hibernate3:hbm2ddl" to generate DLL -->
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>hibernate3-maven-plugin</artifactId>
            <version>3.0</version>
            <configuration>
                <hibernatetool>
                    <classpath>
                        <path location="${project.build.directory}/classes" />
                        <path location="${project.basedir}/src/main/resources/META-INF/" />                                               
                    </classpath>   

                    <jpaconfiguration persistenceunit="galleryPersistenceUnit" />                     
                    <hbm2ddl create="true" export="false" destdir="${project.basedir}/target" drop="true" outputfilename="mysql.sql" format="true" console="true"/>
                </hibernatetool>
            </configuration>
        </plugin>

回答by sendon1982

<property name="hibernate.hbm2ddl.auto" value="update"/>

Add the above code in the persistence.xml under properties tag. "update" will create the table when first time you run your code, after that, only update the table structures if any changes in domain object.

在persistence.xml中的properties标签下添加上面的代码。“更新”将在您第一次运行代码时创建表,此后,仅在域对象发生任何更改时才更新表结构。

回答by Donatello

As Hibernate 4.3+ now implements JPA 2.1 the appropriate way to generate DDL scripts is to use following set of JPA 2.1 properties :

由于 Hibernate 4.3+ 现在实现 JPA 2.1,生成 DDL 脚本的适当方法是使用以下 JPA 2.1 属性集:

<property name="javax.persistence.schema-generation.scripts.action" value="create"/>
<property name="javax.persistence.schema-generation.create-source" value="metadata"/>
<property name="javax.persistence.schema-generation.scripts.create-target" value="target/jpa/sql/create-schema.sql"/>

As it will be run at runtime, you may want to execute this DDL generation at build. There is no supported official maven plugin anymore for Hibernate4 probably because Hibernate team is moving to Gradle.

由于它将在运行时运行,您可能希望在构建时执行此 DDL 生成。 Hibernate4 不再支持官方 maven 插件,可能是因为 Hibernate 团队正在转向 Gradle。

Anyway, this is the JPA 2.1 approach to generate this script programmatically :

无论如何,这是以编程方式生成此脚本的 JPA 2.1 方法:

import java.io.IOException;
import java.util.Properties;

import javax.persistence.Persistence;

import org.hibernate.jpa.AvailableSettings;

public class JpaSchemaExport {

    public static void main(String[] args) throws IOException {
        execute(args[0], args[1]);
        System.exit(0);
    }

    public static void execute(String persistenceUnitName, String destination) {
        System.out.println("Generating DDL create script to : " + destination);

        final Properties persistenceProperties = new Properties();

        // XXX force persistence properties : remove database target
        persistenceProperties.setProperty(org.hibernate.cfg.AvailableSettings.HBM2DDL_AUTO, "");
        persistenceProperties.setProperty(AvailableSettings.SCHEMA_GEN_DATABASE_ACTION, "none");

        // XXX force persistence properties : define create script target from metadata to destination
        // persistenceProperties.setProperty(AvailableSettings.SCHEMA_GEN_CREATE_SCHEMAS, "true");
        persistenceProperties.setProperty(AvailableSettings.SCHEMA_GEN_SCRIPTS_ACTION, "create");
        persistenceProperties.setProperty(AvailableSettings.SCHEMA_GEN_CREATE_SOURCE, "metadata");
        persistenceProperties.setProperty(AvailableSettings.SCHEMA_GEN_SCRIPTS_CREATE_TARGET, destination);

        Persistence.generateSchema(persistenceUnitName, persistenceProperties);
    }

}

As you can see it's very simple !

如您所见,这非常简单!

You can now use this in an AntTask, or MAVEN build like this (for MAVEN) :

你现在可以在 AntTask 中使用它,或者像这样的 MAVEN 构建(对于 MAVEN):

            <plugin>
                <artifactId>maven-antrun-plugin</artifactId>
                <version>1.7</version>
                <executions>
                    <execution>
                        <id>generate-ddl-create</id>
                        <phase>process-classes</phase>
                        <goals>
                            <goal>run</goal>
                        </goals>
                        <configuration>
                            <target>
                                <!-- ANT Task definition -->
                                <java classname="com.orange.tools.jpa.JpaSchemaExport"
                                    fork="true" failonerror="true">
                                    <arg value="${persistenceUnitName}" />
                                    <arg value="target/jpa/sql/schema-create.sql" />
                                    <!-- reference to the passed-in classpath reference -->
                                    <classpath refid="maven.compile.classpath" />
                                </java>
                            </target>
                        </configuration>

                    </execution>
                </executions>
            </plugin>

回答by Krystian

With EclipseLink, you should add property:

使用 EclipseLink,您应该添加属性:

<property name="eclipselink.ddl-generation" value="create-tables"/>

As it is said here: http://www.eclipse.org/eclipselink/documentation/2.4/jpa/extensions/p_ddl_generation.htm

正如这里所说:http: //www.eclipse.org/eclipselink/documentation/2.4/jpa/extensions/p_ddl_generation.htm

My persistence.xml:

我的persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
    <persistence-unit name="appDB" transaction-type="JTA">
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <jta-data-source>LocalMySQL</jta-data-source>
        <class>entity.Us</class>
        <class>entity.Btl</class>
        <class>entity.Co</class>
        <properties>
            <property name="eclipselink.ddl-generation" value="create-tables"/>
        </properties>
    </persistence-unit>
</persistence>