Skip to content

Latest commit

 

History

History
122 lines (82 loc) · 4.06 KB

隐藏在数据库增删改查中的秘密.md

File metadata and controls

122 lines (82 loc) · 4.06 KB

《你不知道的 JAVA》博客系列 💘 隐藏在数据库增删改查中的秘密

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

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

Simple CRUD

上述的使用方式在数据库操作中有个专业名词,叫做 Simple CRUD。这不是什么神奇的功能,大多数数据操作库都会提供这个功能的解决方案。当然,原始的 Mybatis 没有这个功能——所以我们常说:Mybatis 是一个上古时代的框架。

言归正传,对于这样一个 SQL 来说,Mybatis Plus 和 JOOQ 中的 Simple CRUD 分别如下所示:

SELECT * FROM user WHERE username = 'John';

Mybatis Plus

public interface UserMapper extends BaseMapper<User> {
    
}

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
   
}

QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("username", "John");

List<User> userList = userMapper.selectList(queryWrapper);

JOOQ

@Autowired private DSLContext dsl;

List<User> users = dsl.selectFrom(USER).where(USER.USERNAME.eq("John")).fetchInto(User.class);

DSLContext 是什么

JOOQ 不需要什么额外的样板代码,DSLContext 就是 JOOQ 和数据库交互的核心 API——当和 SpringBoot 进行集成时,通过 @Autowired private DSLContext dsl便可在任意地方注入进行使用,就算你在 Controller 里面用也可以。

Q:有好事者问了,那我不用 SpringBoot,使用 JOOQ 还像这样方便吗? A:是的,那更方便了。

DSL.selectFrom(USER).fetch()

查询数据

上面我们已经介绍过了,除此之外还能使用 fetchOne 等其他变体。

User user = dsl.selectFrom(USER).fetchOne();

插入数据

通过 newRecord 创建的对象叫做 UpdatableRecords,这是一个隐含了数据库链接的对象,store 就是插入数据的方法。

UserRecord userRecord = dsl.newRecord(USER);
userRecord.setUsername("[email protected]");
userRecord.setPassword("falr2b9nCVY5hS1o");
userRecord.store();

更新数据

store 是一个 upsert 操作,它不仅能够插入数据,还能够更新数据。这是全自动的,当对象在数据库里已经存在时,再调用 store 就是更新操作。

// 插入新数据
UserRecord userRecord = dsl.newRecord(USER);
userRecord.setUsername("[email protected]");
userRecord.setPassword("falr2b9nCVY5hS1o");
userRecord.store();
// userRecord 插入完毕后再次调用 store 则自动更新
userRecord.setPassword("JHMDoQPKuEcgILE6");
userRecord.store();

删除数据

UserRecord userRecord = dsl.fetchOne(USER, USER.USERNAME.eq("testUserA"));
userRecord.delete();

刷新数据

一个被查询出的UpdatableRecords 代表的数据库状态可能不是最新的,因为别的线程可能在你之后改变了数据库状态。调用 refresh 可以刷新对象的属性为数据库的最新状态。

// 线程A
UserRecord fetchedOne = dsl.fetchOne(USER, USER.USERNAME.eq("[email protected]"));
assertThat(fetchedOne.getPassword()).isEqualTo("falr2b9nCVY5hS1o");

// 线程B
userRecord.setPassword("JHMDoQPKuEcgILE6");
userRecord.store();

// 线程A
fetchedOne.refresh();
assertThat(fetchedOne.getPassword()).isEqualTo("JHMDoQPKuEcgILE6");

致其他语言的开发者

虽然 JOOQ 不是一个 ORM(Mybatis 当然更不是),但是对于使用 C# 和 PHP 及 Ruby 的开发者来说,当你在项目中不得不使用 Java 时,JOOQ 会不会稍微让你对这个领域的 CRUD 生态提起一点点信心?

写在最后

  • 我是 Chuck1sn,一个长期致力于现代 Jvm 生态推广的开发者。
  • 您的回帖、点赞、收藏、就是我持续更新的动力。
  • 举手之劳的一键三连,对我来说是莫大的支持,非常感谢!
  • 关注我的账号,第一时间收到文章推送。