Автоматическая генерация схемы данных из аннотированных классов сущностей JPA - PullRequest
40 голосов
/ 18 ноября 2008

Я использую JPA (реализация Hibernate), чтобы аннотировать классы сущностей для сохранения в реляционной базе данных (MySQL или SQL Server). Существует ли простой способ автоматического создания схемы базы данных (сценариев создания таблиц) из аннотированных классов?

Я все еще на стадии прототипирования и ожидаю частых изменений схемы. Я хотел бы иметь возможность указать и изменить модель данных из аннотированного кода. Grails похож на то, что он генерирует базу данных из классов домена.

Ответы [ 9 ]

13 голосов
/ 01 июля 2009

Создание сценария создания и удаления для данных объектов JPA

Мы используем этот код для генерации отбрасывания и создания операторов: Просто создайте этот класс со всеми классами сущностей и вызовите create / dropTableScript.

При необходимости вы можете вместо этого использовать 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();
    }
}
13 голосов
/ 18 ноября 2008

Вы можете использовать hbm2ddl из Hibernate. Документы здесь .

9 голосов
/ 04 декабря 2008

Как примечание: документацию по созданию схем базы данных с использованием EclipseLink JPA можно найти здесь .

8 голосов
/ 05 декабря 2014

Поскольку 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"/>

Поскольку он будет запускаться во время выполнения, вы можете захотеть выполнить это поколение DDL при сборке. Для Hibernate4 больше не поддерживается официальный плагин maven, вероятно, потому что команда Hibernate переходит на Gradle.

В любом случае, это подход 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);
    }

}

Как видите, все очень просто!

Теперь вы можете использовать это в 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>
6 голосов
/ 28 октября 2009

Вот объяснение того, как использовать класс SchemaExport hibernate, чтобы делать именно то, что вы хотите.

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

2 голосов
/ 27 августа 2013

Вы можете использовать плагин 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>
2 голосов
/ 19 октября 2012

Если вы предпочитаете конфигурирование в 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>
1 голос
/ 03 ноября 2015

С EclipseLink вы должны добавить свойство:

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

Как здесь сказано: http://www.eclipse.org/eclipselink/documentation/2.4/jpa/extensions/p_ddl_generation.htm

My 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 голос
/ 30 августа 2013
<property name="hibernate.hbm2ddl.auto" value="update"/>

Добавьте приведенный выше код в файл persistence.xml под тегом properties. «update» создаст таблицу, когда вы в первый раз запустите свой код, после этого обновите только структуру таблицы, если какие-либо изменения в объекте домена.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...