jpa和hibernate_从JPA到Hibernate的旧版和增强型标识符生成器
jpa和hibernate
JPA標(biāo)識(shí)符生成器
JPA定義了以下標(biāo)識(shí)符策略:
| 汽車 | 持久性提供程序選擇基礎(chǔ)數(shù)據(jù)庫(kù)支持的最合適的標(biāo)識(shí)符策略 |
| 身份 | 標(biāo)識(shí)符由數(shù)據(jù)庫(kù)IDENTITY列分配 |
| 序列 | 持久性提供程序使用數(shù)據(jù)庫(kù)序列來(lái)生成標(biāo)識(shí)符 |
| 表 | 持久性提供程序使用單獨(dú)的數(shù)據(jù)庫(kù)表來(lái)模擬序列對(duì)象 |
在我以前的文章中,我舉例說(shuō)明了所有這些替代標(biāo)識(shí)符策略的優(yōu)缺點(diǎn)。
標(biāo)識(shí)符優(yōu)化器
盡管沒有太多應(yīng)用程序端IDENTITY生成器優(yōu)化(除了配置數(shù)據(jù)庫(kù)標(biāo)識(shí)預(yù)分配),但序列標(biāo)識(shí)符在這方面提供了更大的靈活性。 最常見的優(yōu)化策略之一是基于高/低分配算法 。
為此,Hibernate提供了:
| SequenceHiLoGenerator | 它使用數(shù)據(jù)庫(kù)序列生成hi值,而低值根據(jù)hi / lo算法遞增 |
TableHiLoGenerator | 數(shù)據(jù)庫(kù)表用于生成hi值。 不推薦使用此生成器,而推薦使用MultipleHiLoPerTableGenerator,增強(qiáng)的TableGenerator或SequenceStyleGenerator。 |
| 多重HiLo PerTableGenerator | 它是一個(gè)高/低表生成器,即使對(duì)于多個(gè)標(biāo)識(shí)符序列,也可以使用單個(gè)數(shù)據(jù)庫(kù)表。 |
| SequenceStyleGenerator | 它是先前序列生成器的增強(qiáng)版本。 如果基礎(chǔ)數(shù)據(jù)庫(kù)支持,則使用序列。 如果當(dāng)前數(shù)據(jù)庫(kù)不支持序列,它將切換為使用表來(lái)生成序列值。 當(dāng)以前的生成器具有預(yù)定義的優(yōu)化算法時(shí),可以使用優(yōu)化器策略配置增強(qiáng)型生成器:
池化是默認(rèn)的優(yōu)化器策略。 |
| 表格生成器 | 與MultipleHiLoPerTableGenerator一樣,它可以將一個(gè)表用于多個(gè)標(biāo)識(shí)符生成器,??同時(shí)提供可配置的優(yōu)化器策略。 池化是默認(rèn)的優(yōu)化器策略。 |
JPA到Hibernate標(biāo)識(shí)符映射
擁有如此豐富的生成器,我們不禁要問(wèn)哪個(gè)被用作默認(rèn)的JPA生成器。
盡管JPA規(guī)范并不意味著任何特定的優(yōu)化,但Hibernate寧愿選擇一種優(yōu)化的生成器,而不是總是為每個(gè)新標(biāo)識(shí)符訪問(wèn)數(shù)據(jù)庫(kù)的優(yōu)化生成器。
JPA
我們將定義一個(gè)配置有SEQUENCE JPA標(biāo)識(shí)符生成器的實(shí)體。 單元測(cè)試將保留五個(gè)這樣的實(shí)體。
@Entity(name = "sequenceIdentifier") public static class SequenceIdentifier {@Id@GeneratedValue(generator = "sequence", strategy=GenerationType.SEQUENCE)@SequenceGenerator(name = "sequence", allocationSize = 10)private Long id; }@Test public void testSequenceIdentifierGenerator() {LOGGER.debug("testSequenceIdentifierGenerator");doInTransaction(new TransactionCallable<Void>() {@Overridepublic Void execute(Session session) {for (int i = 0; i < 5; i++) {session.persist(new SequenceIdentifier());}session.flush();return null;}}); }運(yùn)行此測(cè)試,我們將提供以下輸出
Query:{[call next value for hibernate_sequence][]} Generated identifier: 10, using strategy: org.hibernate.id.SequenceHiLoGenerator Generated identifier: 11, using strategy: org.hibernate.id.SequenceHiLoGenerator Generated identifier: 12, using strategy: org.hibernate.id.SequenceHiLoGenerator Generated identifier: 13, using strategy: org.hibernate.id.SequenceHiLoGenerator Generated identifier: 14, using strategy: org.hibernate.id.SequenceHiLoGenerator Query:{[insert into sequenceIdentifier (id) values (?)][10]} Query:{[insert into sequenceIdentifier (id) values (?)][11]} Query:{[insert into sequenceIdentifier (id) values (?)][12]} Query:{[insert into sequenceIdentifier (id) values (?)][13]} Query:{[insert into sequenceIdentifier (id) values (?)][14]}Hibernate選擇使用舊的SequenceHiLoGenerator與向后兼容所有在發(fā)布增強(qiáng)型生成器之前開發(fā)的應(yīng)用程序。 將舊版應(yīng)用程序遷移到新生成器上并非易事,因此增強(qiáng)的生成器是新應(yīng)用程序的更好替代方案。
默認(rèn)情況下,Hibernate更喜歡使用“ seqhilo”生成器,這不是一個(gè)直觀的假設(shè),因?yàn)樵S多人可能期望使用原始的“ sequence”生成器(總是為每個(gè)新的標(biāo)識(shí)符值調(diào)用數(shù)據(jù)庫(kù)序列)。
為了啟用增強(qiáng)的生成器,我們需要設(shè)置以下Hibernate屬性:
properties.put("hibernate.id.new_generator_mappings", "true");給我們以下輸出:
Query:{[call next value for hibernate_sequence][]} Query:{[call next value for hibernate_sequence][]} Generated identifier: 1, using strategy: org.hibernate.id.enhanced.SequenceStyleGenerator Generated identifier: 2, using strategy: org.hibernate.id.enhanced.SequenceStyleGenerator Generated identifier: 3, using strategy: org.hibernate.id.enhanced.SequenceStyleGenerator Generated identifier: 4, using strategy: org.hibernate.id.enhanced.SequenceStyleGenerator Generated identifier: 5, using strategy: org.hibernate.id.enhanced.SequenceStyleGenerator Query:{[insert into sequenceIdentifier (id) values (?)][1]} Query:{[insert into sequenceIdentifier (id) values (?)][2]} Query:{[insert into sequenceIdentifier (id) values (?)][3]} Query:{[insert into sequenceIdentifier (id) values (?)][4]} Query:{[insert into sequenceIdentifier (id) values (?)][5]}新的SequenceStyleGenerator生成的標(biāo)識(shí)符值不同于舊的SequenceHiLoGenerator。 新舊生成器之間的更新語(yǔ)句之所以不同,是因?yàn)樾律善鞯哪J(rèn)優(yōu)化器策略是“池”的,而舊生成器只能使用“ hi / lo”策略。
JPA
@Entity(name = "tableIdentifier") public static class TableSequenceIdentifier {@Id@GeneratedValue(generator = "table", strategy=GenerationType.TABLE)@TableGenerator(name = "table", allocationSize = 10)private Long id; }運(yùn)行以下測(cè)試:
@Test public void testTableSequenceIdentifierGenerator() {LOGGER.debug("testTableSequenceIdentifierGenerator");doInTransaction(new TransactionCallable<Void>() {@Overridepublic Void execute(Session session) {for (int i = 0; i < 5; i++) {session.persist(new TableSequenceIdentifier());}session.flush();return null;}}); }生成以下SQL語(yǔ)句輸出:
Query:{[select sequence_next_hi_value from hibernate_sequences where sequence_name = 'tableIdentifier' for update][]} Query:{[insert into hibernate_sequences(sequence_name, sequence_next_hi_value) values('tableIdentifier', ?)][0]} Query:{[update hibernate_sequences set sequence_next_hi_value = ? where sequence_next_hi_value = ? and sequence_name = 'tableIdentifier'][1,0]} Generated identifier: 1, using strategy: org.hibernate.id.MultipleHiLoPerTableGenerator Generated identifier: 2, using strategy: org.hibernate.id.MultipleHiLoPerTableGenerator Generated identifier: 3, using strategy: org.hibernate.id.MultipleHiLoPerTableGenerator Generated identifier: 4, using strategy: org.hibernate.id.MultipleHiLoPerTableGenerator Generated identifier: 5, using strategy: org.hibernate.id.MultipleHiLoPerTableGenerator Query:{[insert into tableIdentifier (id) values (?)][1]} Query:{[insert into tableIdentifier (id) values (?)][2]} Query:{[insert into tableIdentifier (id) values (?)][3]} Query:{[insert into tableIdentifier (id) values (?)][4]} Query:{[insert into tableIdentifier (id) values (?)][5]}與前面的SEQUENCE示例一樣,Hibernate使用MultipleHiLoPerTableGenerator來(lái)保持向后兼容性。
切換到增強(qiáng)的id生成器:
properties.put("hibernate.id.new_generator_mappings", "true");給我們以下輸出:
Query:{[select tbl.next_val from hibernate_sequences tbl where tbl.sequence_name=? for update][tableIdentifier]} Query:{[insert into hibernate_sequences (sequence_name, next_val) values (?,?)][tableIdentifier,1]} Query:{[update hibernate_sequences set next_val=? where next_val=? and sequence_name=?][11,1,tableIdentifier]} Query:{[select tbl.next_val from hibernate_sequences tbl where tbl.sequence_name=? for update][tableIdentifier]} Query:{[update hibernate_sequences set next_val=? where next_val=? and sequence_name=?][21,11,tableIdentifier]} Generated identifier: 1, using strategy: org.hibernate.id.enhanced.TableGenerator Generated identifier: 2, using strategy: org.hibernate.id.enhanced.TableGenerator Generated identifier: 3, using strategy: org.hibernate.id.enhanced.TableGenerator Generated identifier: 4, using strategy: org.hibernate.id.enhanced.TableGenerator Generated identifier: 5, using strategy: org.hibernate.id.enhanced.TableGenerator Query:{[insert into tableIdentifier (id) values (?)][1]} Query:{[insert into tableIdentifier (id) values (?)][2]} Query:{[insert into tableIdentifier (id) values (?)][3]} Query:{[insert into tableIdentifier (id) values (?)][4]} Query:{[insert into tableIdentifier (id) values (?)][5]}您可以看到這次使用了新的增強(qiáng)型TableGenerator 。
有關(guān)這些優(yōu)化策略的更多信息,請(qǐng)閱讀原始發(fā)行說(shuō)明 。
- 代碼可在GitHub上獲得 。
翻譯自: https://www.javacodegeeks.com/2014/07/from-jpa-to-hibernates-legacy-and-enhanced-identifier-generators.html
jpa和hibernate
總結(jié)
以上是生活随笔為你收集整理的jpa和hibernate_从JPA到Hibernate的旧版和增强型标识符生成器的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 安卓建行怎么查询转账额度(安卓建行)
- 下一篇: 成为Java流大师–第6部分:使用流创建