webentwicklung-frage-antwort-db.com.de

Datenschema aus JPA-annotierten Entitätsklassen automatisch generieren

Ich verwende JPA (Implementierung von Hibernate), um Entitätsklassen so zu kommentieren, dass sie in einer relationalen Datenbank (MySQL oder SQL Server) verbleiben. Gibt es eine einfache Möglichkeit, das Datenbankschema (Tabellenerstellungsskripts) automatisch aus den mit Anmerkungen versehenen Klassen zu generieren?

Ich bin noch in der Prototyping-Phase und erwarte häufige Schemaänderungen. Ich möchte in der Lage sein, das Datenmodell aus dem kommentierten Code zu spezifizieren und zu ändern. Grails ist insofern ähnlich, als es die Datenbank aus den Domänenklassen generiert.

41
Steve Kuo

Sie können hbm2ddl aus dem Ruhezustand verwenden. Die Dokumente sind hier .

14

Erstellen und Löschen eines Skripts für bestimmte JPA-Entitäten

Wir verwenden diesen Code, um die drop- und create-Anweisungen zu generieren: Konstruieren Sie einfach diese Klasse mit allen Entitätsklassen und rufen Sie create/dropTableScript auf.

Bei Bedarf können Sie stattdessen eine persitence.xml und einen Persitance-Unit-Namen verwenden. Sagen Sie einfach etwas und ich poste den Code auch.

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();
    }
}
13
H2000

Zugehöriger Hinweis: Die Dokumentation zum Generieren von Datenbankschemata mit EclipseLink JPA finden Sie hier .

9
hohonuuli

Da Hibernate 4.3+ jetzt JPA 2.1 implementiert, können Sie DDL-Skripten auf folgende Weise generieren:

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

Da es zur Laufzeit ausgeführt wird, können Sie diese DDL-Generierung beim Build ausführen. Es gibt kein offizielles Maven-Plugin mehr für Hibernate4, wahrscheinlich, weil das Hibernate-Team zu Gradle wechselt.

Auf jeden Fall ist dies der JPA 2.1-Ansatz zum programmgesteuerten Generieren dieses Skripts:

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);
    }

}

Wie Sie sehen, ist es sehr einfach!

Sie können dies jetzt in einem AntTask- oder MAVEN-Build wie folgt verwenden (für 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>
8
Donatello

Im Folgenden wird erläutert, wie Sie mit der SchemaExport-Klasse für den Ruhezustand genau das tun, was Sie möchten.

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

6
Andrew Thompson

Wenn Sie es vorziehen, im Frühjahr zu konfigurieren, sollte dies hilfreich sein:

 <!-- 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>

Sie können maven plugin verwenden, um dies zu erreichen.

       <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>
2
sendon1982

Bei EclipseLink sollten Sie die folgenden Eigenschaften hinzufügen:

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

Wie hier gesagt: http://www.Eclipse.org/eclipselink/documentation/2.4/jpa/extensions/p_ddl_generation.htm

Meine 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>
1
Krystian
<property name="hibernate.hbm2ddl.auto" value="update"/>

Fügen Sie den obigen Code in der Datei persistence.xml unter dem Tag properties hinzu. "update" erstellt die Tabelle, wenn Sie den Code zum ersten Mal ausführen. Danach aktualisieren Sie die Tabellenstrukturen nur, wenn sich Änderungen am Domänenobjekt ergeben.

1
sendon1982