GORM Mapping Manifesto ::要么长也要不长

时间:2011-09-29 14:04:58

标签: hibernate testing grails gorm

相当基本的问题,但它的根深蒂固在框架中(并且关于这个主题几乎没有明确的信息),所以我把它放在这里,以便拯救他人的痛苦(并验证我是否正确)在我的思考中。)

有什么问题?

Grails会自动将一个类型为Long的id字段注入您的域(see Beckwith's comment)。使用遗留数据库Grails时默认情况下将Longs映射为bigint,这是一种低效的存储类型,任何处理数百万+记录表的人都会避免这种情况。

几个月前发现这个问题后,我开始着手为我的域ID获取“适当的”列类型。没有Java背景,盲目地我想,Long-bad,Integer-good并将整数类型的hibernate映射方言设置为我在mysql中手动执行的方式

  

registerColumnType(Types.INTEGER,'mediumint unsigned')

然后在我的所有域中定义“Integer id”(根据Bert在上面链接中的评论,没有必要)。一切都在游泳,美妙,与其他事物有关。

快进到Grails 2.0(因为我无法抗拒所有的好东西;-))和Spock。对于我的生活,我无法弄清楚为什么,尽管2.0新的内存GORM和对动态查找器的支持,Domain.findByFoo(fooVal)总是会返回null(是的,我@Mock(域)并填充测试数据)。事实上,在测试本身和@TestFor目标中,唯一有效的GORM方法是save()和get();其他一切都返回null。

我掀起了一个快速测试应用程序,域名+控制器+ spoc规范,并发现了问题的根源:如果你使用除Long以外的属性类型(包括引用的FK),你的@Mock域名将变得毫无用处。

那么,我是否正确地说必须使用Long ID才能充分利用框架? @Mock + @TestFor + Spock是一个令人难以置信的组合!在我走向重构到长路之前,指导得到了赞赏......

1 个答案:

答案 0 :(得分:5)

我无法想象任何真实的场景,其中Integer和Long之间的差异会对性能产生任何显着的差异(这似乎是进行此更改的最初动机)。

如果使用Long工作,但Integer会导致问题,那么使用Long并转移到更重要的任务上。如果您能证明使用Integer会产生任何显着差异,我只会担心这一点。

更新

你是对的,我完全忽略了Grails自动用于Long的数据库类型。您似乎已经知道,您可以在域类的映射闭包中控制数据库类型,例如

class Person {
   Long id

   static mapping = {
      // See here for alternatives to integer, and how they map to DB types
      // http://docs.jboss.org/hibernate/stable/core/manual/en-US/html/mapping.html#mapping-types-basictypes
      id type:'integer'
   }
}

你还提到了评论

  

在代码级处理Long,其中必须指定def foo(Long id){...}和params.id.toLong()而不是Integer

您可以简单地将操作定义为

def myAction = {Person p ->

}

def myAction = {
   Person p = new Person(params)
}

Grails将负责将id请求参数类型转换为Person.id,无论它是Long,Integer,BigDecimal等。