我發現自己處於類似的情況,並且在搜索了很長一段時間之後,我發現從命令行支持此操作的唯一工具是Apache OpenJPA。
它需要一點點配置才能使其正常工作,但它似乎完成了這項工作。 它的工作原理是這樣的:
- 使用Schema Tool從現有的DB模式創建一個.xml文件。
- 可選編輯生成的XML根據自己的喜好(我通過一個搖籃任務運行的整個過程,所以我用Groovy來刪除架構一些不需要的表)
- 使用反向映射生成的.XML JPA實體類工具(沒有足夠的聲望發佈多於2個鏈接,對不起)。此工具還可以採用可選的定製程序類,您可以使用它來進一步定製生成的代碼。
儘管這些工具的文檔聲明它足以在您的類路徑上有一個properties.xml文件來使它們工作,但對於我來說,它們只在我明確指出文件帶有'屬性'arg。
這裏有一些代碼片段可以幫助任何人閱讀這段時間。這在OpenJPA 2.3中進行了測試。0:
生成XML模式(從MSSQL數據庫在我的情況,因此駕駛員在classpath):
java -cp openjpa-all-2.3.0.jar org.apache.openjpa.jdbc.meta.ReverseMappingTool -properties openjpa.xml -metadata none -annotations true -nullableAsObject true -useGenericCollections true -pkg {your package} -directory {output directory} schema.xml
:
java -cp openjpa-all-2.3.0.jar;sqljdbc4.jar org.apache.openjpa.jdbc.schema.SchemaTool -properties openjpa.xml -action reflect -file schema.xml
從XML生成實體示例openjpa.xml(同樣,對於MSSQL DB):
<?xml version="1.0"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0">
<persistence-unit name="Gaya STG">
<properties>
<property name="openjpa.ConnectionURL" value="jdbc:sqlserver://{ip}"/>
<property name="openjpa.ConnectionDriverName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/>
<property name="openjpa.ConnectionUserName" value="{username}"/>
<property name="openjpa.ConnectionPassword" value="{pass}"/>
<property name="openjpa.Log" value="DefaultLevel=WARN, Tool=INFO"/>
</properties>
</persistence-unit>
</persistence>
包含上述所有的任務(同樣,對於MSSQL數據庫)
樣品的build.gradle文件:
import java.util.regex.Pattern
apply plugin: 'java'
dependencies {
compile "org.apache.openjpa:openjpa-all:2.3.0"
compile "sqljdbc4:sqljdbc4:sqljdbc4"
}
task cleanSchemaXml(type: Delete) {
delete file("schema.xml")
}
task generateSchemaXml(type: JavaExec, dependsOn: cleanSchemaXml) {
classpath = configurations.compile
main = "org.apache.openjpa.jdbc.schema.SchemaTool"
args "-properties", getPropertiesFile(),
"-action", "reflect",
"-file", "schema.xml"
doFirst {
println "Generating schema.xml..."
}
doLast {
println "Done generating schema.xml."
println "Updating schema.xml..."
updateSchema()
println "Done updating schema.xml."
}
}
task cleanEntities(type: Delete) {
delete fileTree(dir: "{path/to/your/entities}")
}
task generateEntities(type: JavaExec, dependsOn: [cleanEntities, clean, generateSchemaXml, jar]) {
classpath = files(configurations.compile, jar.archivePath) // Add this module's jar to the executed classpath, so we can use the EntityCustomizer (which is assumed to be in this module).
main = "org.apache.openjpa.jdbc.meta.ReverseMappingTool"
args "-metadata", "none",
"-annotations", "true",
"-nullableAsObject", "true",
"-useGenericCollections", "true",
"-properties", getPropertiesFile(),
// "-customizerClass", "{path.to.your.EntityCustomizer}",
"-directory", "{path/to/your/entities}",
"-pkg", "{your.entity.package}",
"schema.xml"
doFirst {
println "Generating entity classes from schema.xml..."
}
doLast {
println "Done generating entity classes."
}
}
private String getPropertiesFile() {
// File is read directly from the file-system, will not work from a Jar.
return file("src/main/resources/openjpa.xml").getAbsolutePath()
}
private void updateSchema() {
// Only this schema will be kept.
final def schemasToKeep = ['dbo']
// These tables will be removed from the .xml
final def tablesToRemove = [
'ReplicationMonitor', 'DDLEvents', 'AuditTrail', 'AuditTrailErrorLog', 'sysdiagrams', 'table_relations',
'tasks_queue', 'tasks_queue_archive',
'.*history' // Remove all tables ending with 'history'.
].collect { Pattern.compile(it) }
final File xmlFile = file('schema.xml')
// Read xml.
final def xml = new XmlParser().parse(xmlFile)
// Remove all unnecessary schemas.
filterSchemas(xml, schemasToKeep)
// Remove all unnecessary tables.
filterTables(xml, tablesToRemove)
// Save updated xml file.
new XmlNodePrinter(new PrintWriter(new FileWriter(xmlFile))).print(xml)
}
private void filterSchemas(Node xml, List<String> schemasToKeep) {
final List<Node> removedSchemas = []
xml.each { schema ->
final String name = [email protected]
if (!schemasToKeep.contains(name)) {
println("Removing schema: $name")
removedSchemas += schema
}
}
removedSchemas.each { xml.remove(it) }
}
private void filterTables(Node xml, List<Pattern> tablesToRemove) {
xml.each { schema ->
final List<Node> removedTables = []
schema.each { table ->
final String name = [email protected]
if (tablesToRemove.any { it.matcher(name).matches() }) {
println("Removing table: $name")
removedTables += table
}
}
removedTables.each { schema.remove(it) }
}
}
由於任務是如此之小而且定義明確,當然有很少的工具可以做到這一點。許多巨大而昂貴的工具都有一個選項/程序/嚮導來執行相同的操作。但是我發現提供30-50行Perl實際上比找到完全按照你想要的方式完成的工具要快得多。既然你的同事已經不能就工具達成一致,也許寫出你自己的小巧,適應性強的腳本是一條可行的路線。 – 2011-05-12 07:50:53