问一个关于hibernate的OracleDialect问题
但一般做法都是用trigger来调sequence插入ID, 这种方法即安全又灵活,
不知OracleDialect怎样处理这种情况
看看源码就清楚了~~~
你就算用trigger来读sequence生成主键字段,Hibernate还是要多调用一次SQL:select id from ...;
来获取id字段值构造主键类对象返回。
而不用trigger,也有一次SQL:select nextval from sequ来创建主键类
反正都得用两条SQL,区别也不大,你用trigger,对于Hibernate来说,反而更加麻烦,还需要用户去写trigger,索性不用。
再说,让Hibernate来读取sequence,或者让trigger来读取sequence,你觉得有多大差别吗?都不需要用户来管理。
再说用trigger实际上需要两条insert,一条是你在trigger里面写的insert专门用来插入主键字段,然后才是插入其它字段的insert语句。我一点都不觉得用trigger有什么好的地方,我以前用了那么多年Oracle,从来都不用trigger来插入主键。
如果你那么喜欢用trigger,你可以写自行编写一个IDGenerator来实现阿。
JDO就支持trigger创建主键
http://castor.exolab.org/key-generator.html
你说的这个sql语句,Hibernate无法生成这样的sql,所以也根本就用不上trigger创建主键。使用trigger实际上是进行了两次insert,有什么好的,不明白。
你一个表用一个sequence,怎么会有并发问题?除非你所有的表都用一个sequence。再说你觉得用trigger为了插入一条数据要发送两条insert,这样效率不会很低吗?数据库的负担也会加重的。
insert into table_1 (value_1, value_2)
select value_1, value_2 from table2 吗?
这样的sql语句,你索性把主键字段一并复制过去不就得了,何必另外生成主键那么麻烦呢?
在Hibernate里面的1:1关系就是这样处理的,一方采用主键生成技术产生主键,另一方直接把对方的主键拿过来用。
create trigger y before insert on bob
for each row
when (new.a is null)
begin
select x.nextval into :new.a from dual;
end;
当我们插入单条或批量数据时, 不用考虑主键, trigger 会自动加上的.
而且trigger 是单步执行, 不会出现并发访问sequence的情况. 可减少数据库的contention, 而且我们在做表移植等维护操作时可暂时disable trigger, 还有我们可加一些条件在trigger 里, 可对主键强行付值.
总之, 好处多多.
我对hibernate只是使用, 并不打算深研究, 修改就谈不上了
这样的sql语句,你索性把主键字段一并复制过去不就得了,何必另外生成主键那么麻烦呢?*/
这可以是批量插入, 也不光是复制全表, 复制主键有时会冲突的
eg.
insert into table_1 (value_1, value_2)
select value_3, value_4 from table2
where a>50
insert into table_1 (id, value_1, value_2)
select mysequence.nextval, value_3, value_4 from table2
where a>50
mysequence是一个序列,看到了吗?批量插入,也用不着trigger来帮忙读取序列吧!总的来说trigger实现了类似SQL Server的autoincrement字段的作用,如果写JDBC的话,用不着用户来管理,会方便一些,但把序列和字段分开来更灵活,总之我不觉得这样用有什么特殊的好处。
这个功能对Hibernate来说可有可无,但是如果要在Hibernate加上这个功能却很麻烦,因为Hibernate还不支持"insert ... returning ..."的语法,我粗粗的想了想,至少有6个类的源代码要修改,我不太相信Gavin 会为了一个可有可无的功能而大动干戈。