04 July 2006

小東西分享,在一般具備 sequence 的資料庫,例如 Oracle, PostgreSQL, HSQL...等,pk id 我們可以用 sequence generator 來建立:

<id name="id" >
    <generator class="sequence">
       <param name="sequence">seq_person</param>
    </generator>
</id>

按此,執行 session.save(person) 時,hibernate 會下 sql 取得 next value of sequence:

--此處以 HSQL 為例,其他資料庫語法差不多
select next value for seq_person from dual_seq_person

但是當需要連續 insert 資料時,比方說連續 insert 3 筆 person,就會變成:

select next value for seq_person from dual_seq_person
select next value for seq_person from dual_seq_person
select next value for seq_person from dual_seq_person
insert into Person (name, id) values (?, ?)
insert into Person (name, id) values (?, ?)
insert into Person (name, id) values (?, ?)

平白無故多了三個 select,當資料量大的時候就很傷了... 解決的辦法是用另一個 id generator: seqhilo

<id name="id" >
    <generator class="seqhilo">
       <param name="sequence">seq_person</param>
       <param name="max_lo">100</param>
    </generator>
</id>

上面的設定使用 'seqhilo' 這個 generator。它也是依據 seq_person 來產生 id。不同的是,它會事先取得 100 個 sequence 編號 (因為 max_lo 設為 100),供後面的 insert 使用。回頭再來看 insert 三個 person 的 SQL 會是:

select next value for seq_person from dual_seq_person
insert into Person (name, id) values (?, ?)
insert into Person (name, id) values (?, ?)
insert into Person (name, id) values (?, ?)

如此便只剩下一個 select 了。下一次的 select next value... 會等到預先取得的100個用完後,才會再去取一次 (一樣是 100 個)。

使用 seqhilo 前,請先思考該 table 是不是常常會一大批的進資料庫,例如 parse 一些檔案,然後再整批進去?如果是的話,用了才會有顯注的效果。如果不是,用一般的 sequence generator 就夠了。


回響

可以用 Tag <I>、<B>,程式碼請用 <PRE>