从JPA注释的实体类自动生成数据模式
我正在使用JPA(Hibernate的实现)来注释实体类以坚持关系数据库(MySQL或SQL Server)。 有没有一种简单的方法来从注释类自动生成数据库模式(表创build脚本)?
我仍处于原型开发阶段,并预计会频繁更改模式。 我希望能够从注释的代码中指定和更改数据模型。 Grails类似于它从域类生成数据库。
你可以使用Hibernate的hbm2ddl 。 文档在这里 。
为给定的JPA实体生成创build和删除脚本
我们使用这段代码来生成drop和create语句:只需用所有的实体类构造这个类并调用create / dropTableScript。
如果需要,可以使用persitence.xml和persistence单元名称。 只要说一些,我也发布代码。
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(); } }
作为一个相关的说明:使用EclipseLink JPA生成数据库模式的文档可以在这里find。
由于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"/>
由于它将在运行时运行,因此您可能希望在构build时执行此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>
下面是如何使用Hibernate SchemaExport类来完成你想要的解释。
http://jandrewthompson.blogspot.com/2009/10/how-to-generate-ddl-scripts-from.html
如果你喜欢在springconfiguration,那么这应该是有帮助的:
<!-- 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>
你可以使用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>
<property name="hibernate.hbm2ddl.auto" value="update"/>
在properties标签下的persistence.xml中添加上面的代码。 “update”会在你第一次运行你的代码的时候创build表,在那之后,只有在domain对象发生任何变化时才更新表结构。
使用EclipseLink,您应该添加属性:
<property name="eclipselink.ddl-generation" value="create-tables"/>
正如这里所说: http : //www.eclipse.org/eclipselink/documentation/2.4/jpa/extensions/p_ddl_generation.htm
我的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>