在Grails中使用自定义Oracle数据库序列生成ID的方法
适配Oracle序列的GORM ID生成方案
嘿,刚好有过类似的配置经验,给你梳理几种适配Grails 3.3.8 + Oracle 12c的方案,完美匹配你表和序列的命名规则(A_B_C表对应A_B_C_SEQ序列):
方案一:单个域类显式配置
如果只有少数几个域类需要切换序列生成器,可以直接在对应的域类中通过static mapping块指定序列信息:
// 假设域类对应数据库表A_B_C,Groovy类名采用驼峰命名Abc class Abc { Long id // 你的其他业务属性... static mapping = { // 指定ID生成器为sequence,并绑定对应的Oracle序列 id generator: 'sequence', params: [sequence: 'A_B_C_SEQ'] } }
这样GORM在插入新记录时,会自动执行select A_B_C_SEQ.nextVal from dual来获取主键ID,完全符合你的需求。
方案二:全局自动适配(推荐)
如果所有表都遵循表名+_SEQ的序列命名规则,那可以全局配置GORM,不用逐个域类修改,效率更高:
在grails-app/conf/application.groovy中添加全局GORM映射配置:
grails.gorm.default.mapping = { id { // 全局使用sequence生成器 generator 'sequence' // 动态根据域类名生成对应序列名:驼峰转下划线大写 + _SEQ params sequence: { domainClass -> domainClass.name .replaceAll(/([a-z])([A-Z])/, '$1_$2') // 驼峰转下划线 .toUpperCase() + '_SEQ' // 转大写并拼接_SEQ } } }
比如域类Abc会自动映射到序列A_B_C_SEQ,UserInfo会映射到USER_INFO_SEQ,完全匹配你的命名规范。
注意事项
- 确保Oracle数据库中对应的序列已经创建,并且应用使用的数据库用户拥有该序列的
SELECT权限,否则会抛出权限异常。 - 如果之前使用的是增量ID(比如
identity生成器),切换到序列后,要检查序列的当前值是否大于表中已有的最大主键ID,避免插入时出现主键冲突。 - 若需手动获取序列值(特殊业务场景),可以通过GORM的Session执行原生SQL:
def getNextSeqVal() { return Abc.withSession { session -> session.createSQLQuery("select A_B_C_SEQ.nextVal as seq from dual").uniqueResult() } }
内容的提问来源于stack exchange,提问作者Straightfw
相关产品推荐
相关产品推荐

