头图

工程思维落地

《你不知道的 Java 系列》的理念与思维,已落地成一款 全新设计的 Java 脚手架 ,可与博客配套使用。

前言

自从上一篇 Blog 发出以后,有同学提出了这样一种观点:「我管你这那的,数据库我只用增删改查,连分页都不用一样能写程序」。

这篇文章不讨论这种做法的对错,只介绍 JOOQ 针对这种使用方式的解决方案。

DSLContext

DSLContext 是 jooq 和数据库交互时的上下文环境;增删改查和事务管理等数据库相关的一切操作都通过这个核心交互接口进行。所以,使用 Jooq 操作和数据库交互时,总是从 DSLContext 开始的。
当使用 Jooq 和 SpringBoot 进行集成时,通过 @Autowired private DSLContext dsl; 便可注入这个全局唯一的核心交互接口在当前上下文中使用。

查询数据

通过DSLContextselectFrom() 创建一个查询方法查询出 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,十分感谢~


Chuck1sn
16 声望0 粉丝

一个与 IntelliJ IDEA 配套的现代 JAVA 脚手架,你的专属生产力工具。