簡體   English   中英

在Grails中映射舊數據庫表時避免表更改?

[英]Avoiding table changes when mapping legacy database tables in Grails?

我有一個應用程序,其中包含一些從Grails域類自動生成的表,以及一個遺留表(比如表legacy ),這些遺留表是在Grails外部創建的,但正由Grails域類映射。 映射舊數據庫中的列很簡單,但是我想禁用添加額外的字段和索引,Grails會嘗試為這些表添加這些字段和索引。

table changes to the legacy table (changes such as adding indexes, foreign keys, version columns, etc.)? 我的問題是: 如何指示Grails不要對legacy表進行表更改(如添加索引,外鍵,版本列等更改)?

請注意,我不想禁用所有表的自動模式生成/更新,而只禁用映射表legacy

我能夠做這樣的事情的唯一方法是自定義Configuration類:

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
}

我的解決方案要簡單一些。

在Domain類的映射部分中,我只是將version false設置為version false ,並將其命名為'id'列。

class DomainClass {
    static mapping = {
        table 'legacyName'
        version false
        columns{
            id column: 'legacy_id'
        }
    }
}

您可以嘗試使用Hibernate注釋來指定諸如列名,表等之類的內容,而不用創建普通的域類。 有關更多信息,請參見以下鏈接的“使用休眠注釋進行映射”部分。 http://www.grails.org/Hibernate+Integration

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM