Oracle数据库到MySQL数据库迁移过程中的一大难题就是主键生成策略的替换. 如果之前的程序中使用Oracle的Sequence机制来实现主键的自增的话. MySQL中需要使用TableGenerator进行等价替换.
替换的时候, 主要有三个地方需要修改:
- 以注解方式完成hibernate映射的实体;
- 以xml方式完成hibernate映射的实体;
- 数据库存储过程;
注解方式完成hibernate映射的实体的修改
使用Oracle Sequence
假如你之前的程序使用的是Sequence, 这里以一个名为SEQ的Sequence为例, 那么你操作id字段的代码应该长的是下面这个样子:
|
|
使用MySQL表模拟Oracle Sequence
首先你需要在MySQL中建立一个表sys_sequence, 表中有两个字段, 一个是seq_name, 代表Oracle序列的名称, 另一个是current_value, 代表该序列的当前值(注意: 需要将此初始值设定为Oracle数据库中对应序列的当前值.). 表的样子如下:
|
|
. 然后在程序中如下编写:
|
|
xml方式完成hibernate映射的实体的修改
使用Oracle Sequence
之前使用Sequence作为主键生成策略的时候, xml映射文件片段如下:
|
|
使用MySQL表模拟Oracle Sequence
表的结构与前面注解方式所用的表结构相同. 这次我们在xml中使用的generator是org.hibernate.id.enhanced.TableGenerator:
|
|
存储过程的修改
存储过程中, 主要涉及到Sequence的nextval()等方法的替换, 我们同样可以在MySQL中进行模拟.
使用Oracle Sequence
假设我们现在有一个Sequence名为SEQ, 那么我们通常在存储过程中使用如下函数获得SEQ的下一个值:
|
|
使用MySQL模拟Oracle Sequence
首先需要创建一个表格, 用于存储所有序列的名称, 当前值以及递增步长. 这里我们继续沿用前面所述的sys_sequence表, 不过还需要为表新增一个字段increment_by, 我们对照Oracle数据库的设置手动进行increment_by初值的设定.
|
|
然后在数据库中新增两个函数, 一个是currval, 用于获取模拟的Sequence的当前值:
|
|
另一个是nextval, 用户获取模拟的Sequence的下一个值:
|
|
之后在需要使用Sequence的地方, 使用如下语句替代即可:
|
|
小结
如此一来, 就达到了利用MySQL的表来模拟Oracle的Sequence的目的. 以后每当有需要替换的序列, 都在前面建立的sys_sequence中新增一行即可.