工程思維落地
《你不知道的 Java 系列》的理念與思維,已落地成一款 全新設計的 Java 腳手架 ,可與博客配套使用。
前言
自從上一篇 Blog 發出以後,有同學提出了這樣一種觀點:「我管你這那的,數據庫我只用增刪改查,連分頁都不用一樣能寫程序」。
這篇文章不討論這種做法的對錯,只介紹 JOOQ 針對這種使用方式的解決方案。
DSLContext
DSLContext 是 jooq 和數據庫交互時的上下文環境;增刪改查和事務管理等數據庫相關的一切操作都通過這個核心交互接口進行。所以,使用 Jooq 操作和數據庫交互時,總是從 DSLContext 開始的。
當使用 Jooq 和 SpringBoot 進行集成時,通過 @Autowired private DSLContext dsl; 便可注入這個全局唯一的核心交互接口在當前上下文中使用。
查詢數據
通過DSLContext 的 selectFrom() 創建一個查詢方法查詢出 USER 表的數據後再使用 fetchInto 把查詢出來的數據庫記錄轉換為一個 POJO
List<User> users = dsl.selectFrom(USER).fetchInto(User.class);
selectFrom(USER) 中的 USER 是一個數據庫表的對象,它是通過 JooqCodeGen 插件自動生成的。
public class User extends TableImpl<UserRecord> {
private static final long serialVersionUID = 1L;
/** The reference instance of <code>mjga.user</code> */
public static final User USER = new User();
/** The class holding records for this type */
@Override
public Class<UserRecord> getRecordType() {
return UserRecord.class;
}
}
List<User> 和 User.class 是一個 POJO 用以承載我們的數據,它也是通過 JooqCodeGen 插件自動生成的。
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String username;
private OffsetDateTime createTime;
private String password;
private Boolean enable;
}
插入數據
Jooq 的 modify 操作提供了很多種風格;像下面這樣的看起來像 JPA 的使用方式的被稱為 SimpleCRUD
UserRecord userRecord = dsl.newRecord(USER);
userRecord.setUsername("9hrb5Fv@gmail.com");
userRecord.setPassword("falr2b9nCVY5hS1o");
userRecord.store();
通過 newRecord 創建的對象叫做 UpdatableRecords,這是一個隱含了數據庫鏈接的對象。這個對象除了本身包含的 Record 屬性外,還有和數據庫交互的方法。store 就是插入數據的方法——這有點像 JPA 的 Entity,將面向對象編程語言中的對象模型與關係數據庫中的數據模型進行了映射。
更新數據
store不僅能夠插入數據,它還能夠更新數據。這都是自動的——當對象在數據庫裏已經存在時,再調用 store 就是更新操作。
// 插入新數據
UserRecord userRecord = dsl.newRecord(USER);
userRecord.setUsername("9hrb5Fv@gmail.com");
userRecord.setPassword("falr2b9nCVY5hS1o");
userRecord.store();
// userRecord 插入完畢後再次調用 store 自動更新
userRecord.setPassword("JHMDoQPKuEcgILE6");
userRecord.store();
刷新數據
一個被查詢出的UpdatableRecords 代表的數據庫狀態可能不是最新的,因為別的線程可能在你之後改變了數據庫狀態。調用 refresh 可以刷新對象的屬性為數據庫的最新狀態。
UserRecord fetchedOne = dsl.fetchOne(USER, USER.USERNAME.eq("9hrb5Fv@gmail.com"));
assertThat(fetchedOne.getPassword()).isEqualTo("falr2b9nCVY5hS1o");
userRecord.setPassword("JHMDoQPKuEcgILE6");
userRecord.store();
fetchedOne.refresh();
assertThat(fetchedOne.getPassword()).isEqualTo("JHMDoQPKuEcgILE6");
刪除數據
UserRecord userRecord1 = dsl.fetchOne(USER, USER.USERNAME.eq("testUserA"));
userRecord1.delete();
SimpleCRUD
以上示例都叫做 SimpleCRUD,大多數單表操作通過這種風格都可以完成。只要掌握這些,就可以覆蓋掉 50%-80% 的 CRUD 工作。剩下的內容我們將在後續的章節中繼續講解。完整的代碼示例你可以在這個 Github 倉庫中找到,如果你覺得有用,請幫忙點一個 Star,十分感謝~