grails 有限的表创建

Posted

技术标签:

【中文标题】grails 有限的表创建【英文标题】:grails limited table creation 【发布时间】:2010-10-14 15:53:20 【问题描述】:

我想使用 Grails 功能在有限的基础上创建/更新数据库表。具体来说,我希望 Grails 管理一些表,但不是全部。

有没有办法限制 Grails 管理的表,或者它是全有还是全无?

【问题讨论】:

【参考方案1】:

由于 Grails 使用 Hibernate 的 HBM2DDL 功能,因此通常是全有或全无。但是您可以使用自定义配置子类拦截该过程。这是一个扩展 GrailsAnnotationConfiguration 并覆盖所有三种 SQL 生成方法的示例:

package com.yourcompany.yourapp;

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.tool.hbm2ddl.DatabaseMetadata;

public class MyConfiguration extends GrailsAnnotationConfiguration 

   private static final String[] IGNORE_NAMES =  "foo", "bar" ;

   @Override
   public String[] generateDropSchemaScript(Dialect dialect) throws HibernateException 
      return prune(super.generateDropSchemaScript(dialect));
   

   @Override
   public String[] generateSchemaCreationScript(Dialect dialect) throws HibernateException 
      return prune(super.generateSchemaCreationScript(dialect));
   

   @Override
   public String[] generateSchemaUpdateScript(Dialect dialect, DatabaseMetadata databaseMetadata)
         throws HibernateException 
      return prune(super.generateSchemaUpdateScript(dialect, databaseMetadata));
   

   private String[] prune(String[] script) 
      List<String> pruned = new ArrayList<String>();
      for (String command : script) 
         for (String ignoreName : IGNORE_NAMES) 
            if (!command.toLowerCase().contains(" table " + ignoreName + " ")) 
               pruned.add(command);
            
         
      
      return pruned.toArray(new String[pruned.size()]);
   

您不需要覆盖所有三个,例如您可以让创建通过但删除更新。

这会在 grails-app/conf/DataSource.groovy 中注册:

dataSource 
   pooled = true
   driverClassName = ...
   username = ...
   password = ...
   configClass = com.yourcompany.yourapp.MyConfiguration

请注意,该类必须用 Java 编写,因为基类中的私有方法与 Groovy 添加到所有 groovy 类的方法发生冲突。

【讨论】:

工作就像一个魅力。谢谢伯特! private String[] prune(String[] script) List pruned = new ArrayList();对于(字符串命令:脚本)布尔忽略=假; for (String ignoreName : IGNORE_NAMES) if (command.toLowerCase().contains(" table " + ignoreName.toLowerCase() + " ")) ignore = true;休息; if (!ignore) pruned.add(command); return pruned.toArray(new String[pruned.size()]); 更新:HIbernate 4 已弃用更新方法。如果您要覆盖 generateSchemaUpdateScript 方法,请查看替换方法。它具有不同的返回值类型。 public String[] generateSchemaUpdateScript(Dialect dialect, DatabaseMetadata databaseMetadata) 已弃用:改用 generateSchemaUpdateScriptList(Dialect, DatabaseMetadata)【参考方案2】:

感谢史蒂夫的修复。我正在重新发布上面的修复程序,但已针对 *** 进行了格式化。当我第一次尝试这个时,我错过了原来的if (!command.toLowerCase()...) 将修复中的逻辑反转为if (command.toLowerCase()...),这实际上使它在我的配置/数据源中看起来像dbCreate = "create-drop" .groovy 没有任何效果。我什至从这个页面的 html 源代码中查看代码的预期换行符,但仍然错过了重要的逻辑:-( 一旦我输入正确,它就很好用。

private String[] prune(String[] script) 
    List<String> pruned = new ArrayList<String>();
    for (String command : script) 

        boolean ignore = false;

        for (String ignoreName : IGNORE_NAMES) 
            if (command.toLowerCase().contains(" table " + ignoreName.toLowerCase() + " ")) 
                ignore = true;
                break;
            
            

        if (!ignore) 
            pruned.add(command);
        
    
    return pruned.toArray(new String[pruned.size()]);

【讨论】:

以上是关于grails 有限的表创建的主要内容,如果未能解决你的问题,请参考以下文章

使用 Grails 作为框架时尝试查看 H2 数据库中的表

Grails 域是不是可能没有“id”?

Grails 2.4.4 数据源“create-drop”无法删除所有具有 FK 的表

在 Grails 中映射遗留数据库表时避免表更改?

在 Java 或 Grails 应用程序中动态创建实体、Spring 存储库和 facelets 页面

尝试在使用Grails作为框架时在H2数据库中查看表