2

我有以下课程:


class Catalog {
  static mapping = {
    id composite:['name', 'manufacturer']
    columns {
      name column:'cat_name'
      manufacturer column:'manuf_id'
    }
  }
  String name
  Manufacturer manufacturer
}

class Order {
  static mapping = {
    columns {
      // How to rename foreign keys as cat_name, manuf_id?
    }
  }
  Catalog catalog // creates catalog_name, catalog_manufacturer_name
}

目前,使用属性 catalog_name 和 catalog_manufacturer_name 生成了一个 Order 表(它们引用了 Catalog 表的复合主键)。

我需要在 Order 表中将这些生成的列重命名为 cat_name 和 manuf_id 以使用现有数据库。这可能吗?如果可以,怎么做?

4

3 回答 3

4

这解决了我的问题(grails 2.0.4):

http://jira.grails.org/browse/GRAILS-4504?focusedCommentId=64996&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-64996

我的情况:

class GroupMessage implements Serializable {

    Group group
    Integer messageId

    static mapping = {
        datasources(['ds1'])
        table 't_group_msg'
        version false
        id composite: ['group', 'messageId'], generator: 'assigned'
        group column:'grpid'
        messageId column:'msgid', type:int
    }
}

class GroupMessageDetail implements Serializable {

    GroupMessage groupMessage
    Integer detailId
    String message
    String url

    static mapping = {
        datasources(['ds1'])
        table 't_group_msg_det'
        version false
        id composite: ['groupMessage', 'detailId'], generator: 'assigned'
        columns {
            groupMessage {
                column name: 'grpid'
                column name: 'msgid'
            }
            detailId column:'id', type:int
            message column:'sms'
            url column:'url'
       }
}
于 2012-07-30T22:55:46.897 回答
2

使用 GORM 配置是不可能的,但您可以使用自定义配置类来做到这一点:

package com.foo.bar;

import java.util.Collection;
import java.util.Iterator;

import org.codehaus.groovy.grails.orm.hibernate.cfg.DefaultGrailsDomainConfiguration;
import org.hibernate.MappingException;
import org.hibernate.mapping.Column;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.RootClass;

public class CompositeAwareHibernateConfiguration extends DefaultGrailsDomainConfiguration {

   private static final long serialVersionUID = 1;

   private boolean _alreadyProcessed;

   @SuppressWarnings("unchecked")
   @Override
   protected void secondPassCompile() throws MappingException {
      super.secondPassCompile();

      if (_alreadyProcessed) {
         return;
      }

      for (PersistentClass pc : (Collection<PersistentClass>)classes.values()) {
         if (pc instanceof RootClass) {
            RootClass root = (RootClass)pc;
            if ("com.foo.bar.Order".equals(root.getClassName())) {
               for (Iterator iter = root.getTable().getColumnIterator(); iter.hasNext(); ) {
                  Column column = (Column)iter.next();
                  if ("catalog_name".equals(column.getName())) {
                     column.setName("cat_name");
                  }
                  else if ("catalog_manufacturer_id".equals(column.getName())) {
                     column.setName("manuf_id");
                  }
               }
            }
         }
      }

      _alreadyProcessed = true;
   }
}

将类放在 src/java 中,并在 DataSource.groovy 中注册:

dataSource {
   pooled = true
   driverClassName = ...
   username = ...
   password = ...
   configClass = com.foo.bar.CompositeAwareHibernateConfiguration
}
于 2010-02-05T04:20:43.230 回答
2

我已经为需要它的任何域类编写了一个解决方案,并且您不需要每次都 readapt。

class Catalog {
  static mapping = {
    id composite:['name', 'manufacturer']
    columns {
      name column:'cat_name'
      manufacturer column:'manuf_id'
    }
  }
  String name
  Manufacturer manufacturer
}

class Order {
  Catalog catalog
  static mapping = {
  }
  static foreigners = [
    catalog : [name : "catalog_name",
              manufacturer: "catalog_manufacturer_name"]
  ]
}

这是我编写的 GORM 配置类,用于在域类中使用外国人。

package my.app.package
import java.util.Collection;
import org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsAnnotationConfiguration;
import org.hibernate.MappingException;
import org.hibernate.mapping.Column;
import org.hibernate.mapping.ForeignKey;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.RootClass;
class MyCustomGrailsAnotationConfiguration extends GrailsAnnotationConfiguration{
    private static final long serialVersionUID = 1;
    private boolean _alreadyProcessed=false;
    @SuppressWarnings("unchecked")
    @Override
    protected void secondPassCompile() throws MappingException {
        super.secondPassCompile();
        if(_alreadyProcessed){
            return;
        }
        classes.values().each{rootClass ->
            if(rootClass instanceof RootClass){
                def domainClass= null
                Boolean hasForeigners=false
                try{
                    domainClass=Class.forName(rootClass.entityName,false,Thread.currentThread().getContextClassLoader())
                    hasForeigners = domainClass.metaClass.hasProperty(domainClass, 'foreigners')
                }catch(Exception e){}
                if(domainClass && hasForeigners){
                    rootClass?.table?.foreignKeyIterator?.each{fKey->
                        fKey?.columnIterator?.each{column->
                            domainClass.foreigners?.each{attrName,columns ->
                                columns.each{columnItmName,columnItmValue->
                                    def exp=attrName+"_"
                                    columnItmName.split("").each{exp+=(it==~/[A-Z]/) ? "_"+it:it}
                                    exp=exp.toLowerCase()+".(id)\$"
                                    //println "Expression:"+exp
                                    if(column.name.matches(exp)){
                                        //println "Match:"+column.name+" changing to "+columnItmValue
                                        column.name=columnItmValue
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        _alreadyProcessed = true;
    }
}

将 my.app.package.MyCustomGrailsAnotationConfiguration.groovy 类放在 src/groovy/my/app/package/MyCustomGrailsAnotationConfiguration.groovy 中,并在 DataSource.groovy 中注册:

dataSource {
   pooled = true
   driverClassName = ...
   username = ...
   password = ...
   configClass = my.app.package.MyCustomGrailsAnotationConfiguration
}

我希望这对你有用。感谢@carlosmain 的帮助

于 2011-09-22T16:44:14.150 回答