使用活动记录执行CRUD
本文是我們學院課程的一部分,標題為jOOQ –類型安全的數據庫查詢 。
在SQL和特定關系數據庫很重要的Java應用程序中,jOOQ是一個不錯的選擇。 當JPA / Hibernate抽象過多,JDBC過多時,這是一種替代方法。 它顯示了一種現代的領域特定語言如何可以極大地提高開發人員的生產率,從而將SQL內部化為Java。
在本課程中,我們將看到如何使用jOOQ有效地查詢數據庫。 在這里查看 !
目錄
1.簡介 2.簡單的活動記錄操作 3.樂觀鎖1.簡介
雖然SQL是一種非常有表現力的語言,但是您的大多數SQL可能都是CRUD(創建,讀取,更新,刪除)。 編寫這樣的CRUD既無聊又重復,這就是為什么像Hibernate這樣的ORM出現并成功提高開發人員生產力的原因。 但是,當您經常只想對表中的單個記錄進行操作時,Hibernate對您的體系結構進行了許多假設(和限制)。
也可以從org.jooq.academy.section2包中獲得本節中顯示的示例 。
2.簡單的活動記錄操作
jOOQ知道“活動記錄”或UpdatableRecords ,可以將其裝入“特殊”種類的SELECT語句,然后在內部跟蹤臟標志。 這是在不編寫過多SQL的DATE_OF_BIRTH下更新作者DATE_OF_BIRTH :
AuthorRecord author = dsl.selectFrom(AUTHOR).where(AUTHOR.ID.eq(1)).fetchOne(); author.setDateOfBirth(Date.valueOf("2000-01-01")); author.store();由于上面的示例僅通過selectFrom()從一個表中進行選擇,因此jOOQ知道結果記錄類型將為AuthorRecord ,即由代碼生成器生成的對象。 AuthorRecord實現UpdatableRecord ,它具有多種有用的方法:
- store() INSERT或UPDATE記錄
- insert() INSERT記錄
- update() UPDATE記錄
- delete() DELETE記錄
- refresh()從數據庫刷新記錄
以下示例部分將指導您完成創建,讀取,更新,刪除此類記錄的整個生命周期:
AuthorRecord author;// Create a new record and store it to the database. This will perform an INSERT statement author = dsl.newRecord(AUTHOR); author.setId(3); author.setFirstName("Alfred"); author.setLastName("Hitchcock"); author.store();// Read the record by refreshing it based on the primary key value author = dsl.newRecord(AUTHOR); author.setId(3); author.refresh();// Update the record with a new value author.setDateOfBirth(Date.valueOf("1899-08-13")); author.store();// Delete the record again author.delete();jOOQ的UpdatableRecords跟蹤每列內部的“臟”或“已更改”狀態,在調用store()以便僅插入/更新已在UpdatableRecord更改的值時使用該狀態。
3.樂觀鎖
執行CRUD時,并發數據訪問通常是一個可以通過兩種方法解決的問題:
- 通過使用悲觀鎖定
- 通過使用樂觀鎖定
悲觀鎖定很少是一個好選擇,因為當兩個進程以不同的順序鎖定表中的幾行以等待彼此完成時,死鎖很容易發生。 樂觀鎖定是更合適的解決方案。 一個過程可能很幸運,可以在另一個過程嘗試(失敗)之前完成交易。 這是jOOQ的工作方式。
在我們的樣本數據中, BOOK表具有一個特殊的“系統”列,稱為REC_TIMESTAMP 。 每當您在BookRecord上運行CRUD操作時,jOOQ都會完全管理此列的內容,而不必保持最新狀態。 考慮以下代碼示例:
// Enable optimistic locking DSLContext dsl = DSL.using(connection, new Settings().withExecuteWithOptimisticLocking(true));// Perform the CRUD with the above setting BookRecord book1 = dsl.selectFrom(BOOK).where(BOOK.ID.eq(1)).fetchOne(); book1.setTitle("New Title"); book1.store();jOOQ現在將執行一條UPDATE語句,該語句還將更新并檢查REC_TIMESTAMP值:
update "PUBLIC"."BOOK" set "PUBLIC"."BOOK"."TITLE" = 'New Title',"PUBLIC"."BOOK"."REC_TIMESTAMP" = timestamp '2014-09-08 18:40:39.416' where ("PUBLIC"."BOOK"."ID" = 1 and "PUBLIC"."BOOK"."REC_TIMESTAMP" is null)注意如何在SET子句REC_TIMESTAMP設置為當前時間,同時在WHERE子句中還將其檢查為NULL (示例數據庫中的初始值)。
如果我們現在有兩個相互競爭的進程(或同一進程中的代碼部分)進行此更新,如下所示:
BookRecord book1 = dsl.selectFrom(BOOK).where(BOOK.ID.eq(1)).fetchOne(); BookRecord book2 = dsl.selectFrom(BOOK).where(BOOK.ID.eq(1)).fetchOne();book1.setTitle("New Title"); book1.store();book2.setTitle("Another Title"); book2.store();…然后,在對store()的第二次調用(縮短的堆棧跟蹤)上,我們將見證DataChangedException :
org.jooq.exception.DataChangedException: Database record has been changed or doesn't exist any longerat org.jooq.impl.UpdatableRecordImpl.checkIfChanged(UpdatableRecordImpl.java:420)at org.jooq.impl.UpdatableRecordImpl.storeUpdate(UpdatableRecordImpl.java:193)at org.jooq.impl.UpdatableRecordImpl.store(UpdatableRecordImpl.java:129)at org.jooq.impl.UpdatableRecordImpl.store(UpdatableRecordImpl.java:121)樂觀鎖定適用于UpdatableRecord操作,包括insert() , update()和delete() 。
jOOQ支持三種樂觀鎖定模式:
- 使用專用的TIMESTAMP列來跟蹤修改日期
- 使用專用的NUMBER列跟蹤版本號
- 使用價值比較。 如果沒有為代碼生成器配置任何時間戳或版本列,則為默認設置
翻譯自: https://www.javacodegeeks.com/2015/09/perform-crud-with-active-records.html
總結
以上是生活随笔為你收集整理的使用活动记录执行CRUD的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 海外 谷歌 app api_Google
- 下一篇: 银行转账24小时内可以撤销是立刻退回吗?