Oracle实现主键自增长的几种方式

来源:互联网 发布:区和县的区别 知乎 编辑:程序博客网 时间:2024/06/10 17:28

使用SQLServer、MySQL时,无论我们使用的是直接JDBC连接数据库,还是通过Hibernate操纵数据库,我们只需要设置一个选项或者一行注解便可以实现主键的自增长。

但Oracle没有直接提供主键自增长的功能,这里我们可以使用两种方式来解决主键自增长的问题。

第一种,通过序列以及触发器实现主键自增长。

这种方式适用于直接使用JDBC连接数据库。这种方式将主键自增长的任务完全交给数据库,我们无需在代码层面上进行任何控制。

第二种,通过序列以及Hibernate配置实现自增长。

这种方式适用于通过Hibernate连接数据库的方式。这种方式在数据库上创建序列,通过配置在POJO类上的注释,让Hibernate去调用数据库的序列实现自增长。

这两种方式都是通过Oracle的序列实现自增长,但第一种通过数据库的触发器在插入的时候自动插入主键。而后者则由Hibernate自动完成获取主键,插入主键这一操作。

在用到Hibernate进行开发的项目中,建议选择第二种进行配置。因为如果通过第一种方式进行配置,则Hibernate无法获取到其主键的值,在插入的时候Hibernate会提示:父类主键未找到(即主键无值)。

进一步,Hibernate的级联增加也会因为无法获取到主键而无法插入数据到关系表中。

一、通过序列以及触发器实现主键自增长

首先,为每个表创建一个序列:

复制代码
1 /* 创建序列 */2 --为bitinfo表的主键创建序列3 create sequence bitinfo_id_seq4 increment by 15 start with 1;6 --为product表的主键创建序列7 create sequence product_id_seq8 increment by 19 start with 1;
复制代码

接着,为相对于的表创建触发器:

复制代码
 1 /* 创建触发器(两个触发器请分开执行) */ 2 --为bitinfo表创建触发器 3 create or replace trigger trg_bitinfo 4 before insert on t_yw_bitinfo 5 for each row 6 begin 7 select bitinfo_id_seq.nextval into :new.id from dual; 8 end trg_bitinfo; 9 --为product表创建触发器10 create or replace trigger trg_product11 before insert on t_yw_product12 for each row13 begin 14 select product_id_seq.nextval into :new.id from dual;15 end trg_product;
复制代码

你可以使用下面的语句查看序列是否已经创建:

1 --查看某位用户的所有序列  2 select SEQUENCE_OWNER,SEQUENCE_NAME from dba_sequences where sequence_owner='CSY';3 --删除序列4 drop sequence bitinfo_id_seq;

二、通过序列以及Hibernate配置实现自增长

首先,为每个表创建一个序列:

复制代码
1 /* 创建序列 */2 --为bitinfo表的主键创建序列3 create sequence bitinfo_id_seq4 increment by 15 start with 1;6 --为product表的主键创建序列7 create sequence product_id_seq8 increment by 19 start with 1;
复制代码

接着,把POJO类主键上的注释改为:

1     @Id2     @SequenceGenerator(name = "prodG",sequenceName="PRODUCT_ID_SEQ",allocationSize=1)3     @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "prodG")4     public int getId() {5         return id;6     } 

其中第2、3行声明该主键使用序列来实现自增长,第2行的sequenceName指定了序列名(即在上一步骤所创建的序列名)。

第2行的allocationSize指定了自增长的大小,这里手动设置为1。在Hibernate Annotation版本(大概是3.2版本)之前,如果不设置这个属性,其默认为1。

但在3.2版本之后如果不设置allocationSize,则其自增长大小变成50。

原创粉丝点击