我有一個應用程序,其中包含一些自動生成的Grails域類和一個遺留表(表legacy
),它們是在Grails之外創建的,但由Grails域類映射。映射遺留數據庫中的列是微不足道的,但我希望禁用添加額外的字段和索引,Grails會爲所述表格添加額外的字段和索引。在Grails中映射遺留數據庫表時避免表更改?
我的問題是:我怎麼教的Grails不作變化(如添加索引,外鍵,版本柱等)任何表更改legacy
表?
請注意,我不想禁用所有表的自動模式生成/更新,僅限映射表legacy
。
我有一個應用程序,其中包含一些自動生成的Grails域類和一個遺留表(表legacy
),它們是在Grails之外創建的,但由Grails域類映射。映射遺留數據庫中的列是微不足道的,但我希望禁用添加額外的字段和索引,Grails會爲所述表格添加額外的字段和索引。在Grails中映射遺留數據庫表時避免表更改?
我的問題是:我怎麼教的Grails不作變化(如添加索引,外鍵,版本柱等)任何表更改legacy
表?
請注意,我不想禁用所有表的自動模式生成/更新,僅限映射表legacy
。
我已經能夠做到這樣的東西,唯一的方法是一個自定義配置類:
package com.foo.bar;
import java.util.ArrayList;
import java.util.List;
import org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsAnnotationConfiguration;
import org.hibernate.HibernateException;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.HSQLDialect;
import org.hibernate.tool.hbm2ddl.DatabaseMetadata;
public class DdlFilterConfiguration extends GrailsAnnotationConfiguration {
private static final String[] IGNORE_NAMES = { "legacy" };
@Override
public String[] generateSchemaCreationScript(Dialect dialect) throws HibernateException {
return prune(super.generateSchemaCreationScript(dialect), dialect);
}
@Override
public String[] generateDropSchemaScript(Dialect dialect) throws HibernateException {
return prune(super.generateDropSchemaScript(dialect), dialect);
}
@Override
public String[] generateSchemaUpdateScript(Dialect dialect, DatabaseMetadata databaseMetadata) throws HibernateException {
return prune(super.generateSchemaUpdateScript(dialect, databaseMetadata), dialect);
}
private String[] prune(String[] script, Dialect dialect) {
if (dialect instanceof HSQLDialect) {
// do nothing for test env
return script;
}
List<String> pruned = new ArrayList<String>();
for (String command : script) {
if (!isIgnored(command)) {
pruned.add(command);
}
}
return pruned.toArray(new String[pruned.size()]);
}
private boolean isIgnored(String command) {
command = command.toLowerCase();
for (String table : IGNORED_NAMES) {
if (command.startsWith("create table " + table + " ") ||
command.startsWith("alter table " + table + " ") ||
command.startsWith("drop table " + table + " ")) {
return true;
}
}
return false;
}
}
在SRC/JAVA將這個(不能寫在Groovy因爲一個奇怪的編譯錯誤),並使用'configClass'屬性在DataSource.groovy中註冊它:
dataSource {
pooled = true
driverClassName = ...
username = ...
password = ...
dialect = ...
configClass = com.foo.bar.DdlFilterConfiguration
}
您可以嘗試使用Hibernate註釋來指定諸如列名,表等等之類的內容,而不是創建普通的域類。有關更多信息,請參閱以下鏈接的「映射Hibernate註釋」部分。 http://www.grails.org/Hibernate+Integration
我的解決方案有點簡單。
在Domain類的映射部分,我只設置了version false
,並將其命名爲'id'列。
class DomainClass {
static mapping = {
table 'legacyName'
version false
columns{
id column: 'legacy_id'
}
}
}
這可能在2009年當這個問題首次被問到時是不可能的;然而,現在肯定是正確的答案。 – Michael 2015-06-25 21:21:18