vir*_*yes 4 testing grails hibernate grails-orm
相当基本的问题,但它的根源深入到框架中(并且关于这个主题几乎没有确切的信息),所以我把它放在这里以便拯救他人的痛苦(并且在我的思考中验证我是否正确) ).
问题是什么?
Grails会自动将一个类型为Long的id字段注入您的域(请参阅Beckwith的评论).使用遗留数据库Grails时默认情况下将Longs映射为bigint,这是一种低效的存储类型,任何处理大量+记录表的人都会避免这种情况.
几个月前发现这一点后,我开始着手为我的域ID获取"适当的"列类型.没有Java背景,盲目地我想,Long-bad,Integer-good并将整数类型的hibernate映射方言设置为我将在mysql中手动执行的操作
registerColumnType(Types.INTEGER,'mediumint unsigned')
然后在我的所有域中定义"整数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是一个令人难以置信的组合!在我走向重构到长路之前,指导得到了赞赏......
我无法想象任何真实的场景,其中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'
}
}
Run Code Online (Sandbox Code Playgroud)
你还提到了评论
在代码级别处理Long,其中必须指定def foo(Long id){...}和params.id.toLong()而不是Integer
您可以简单地将操作定义为
def myAction = {Person p ->
}
Run Code Online (Sandbox Code Playgroud)
要么
def myAction = {
Person p = new Person(params)
}
Run Code Online (Sandbox Code Playgroud)
Grails将负责将id请求参数转换为类型Person.id,无论它是Long,Integer,BigDecimal等.
| 归档时间: |
|
| 查看次数: |
1675 次 |
| 最近记录: |