jOOQ的DSL,像任何流畅的API一样,有一个很大的注意事项。你很容易忘记调用.execute() 。而当你这样做的时候,你有可能会盯着你的代码好几分钟,因为一切看起来都很完美:
ctx.insertInto(T)
.columns(T.A, T.B)
.values(1, 2);
盯着...盯着...盯着...为什么没有插入那一行?
"啊呀,又来了!!"
这就是它的做法:
ctx.insertInto(T)
.columns(T.A, T.B)
.values(1, 2)
.execute();
原则上,这种错误可能发生在任何流畅的API上。比如说。StringBuilder
sb.append("a").append("b"); // Not consuming the result
或者流:
Stream.of(1, 2).peek(System.out::println); // Not so much peeking
但通常不会发生那么多,因为与jOOQ的区别在于:
- jOOQ的DML语句(
INSERT,UPDATE,DELETE,MERGE)和DDL语句(CREATE,ALTER,DROP,TRUNCATE),以及其他一些产生的副作用 - 这个副作用是我们唯一关心的事情。其结果(更新次数)大部分是不相关的
因此,我们并不关心execute() 的结果,它是一个int 。没有人忘记在一个jOOQResultQuery 上调用fetch() 。
ctx.select(T.A, T.B)
.from(T); // Well duh
因为如果不调用fetch() 或类似的东西,我们就不会得到任何结果,而我们想要这些结果,就像调用StringBuilder 或Stream 。但我们不想要execute() 的结果。
因此,即使是我们,在编写jOOQ的集成测试时,偶尔也会忘记调用这个愚蠢的小方法。
再也不会了!
当它在本周再次发生时...
花了10分钟试图弄清楚为什么我的JOOQ插入似乎不工作了...
... 忘记了`.execute()`
... 该死的令人震惊的同事在这里
- 💀 r͍̣̼ͯ̑ͪ ̽ͦfͤ͐ĺ̫̺̙̃͐c͙̪̤̘̯ 💀 (@_fletchr)March 25, 2021
...我终于创建了一个问题来思考这个问题:https://github.com/jOOQ/jOOQ/issues/11718。我还创建了一个问题,想知道JetBrains是否能对此做些什么:https://youtrack.jetbrains.com/issue/IDEA-265263
而他们已经可以了!除了org.jetbrains.annotations.Contract 注解,显然正是因为这个原因才有的,也可以在每一个 "其返回值需要检查 "的方法上模仿JSR-305@CheckReturnValue 注解(即一个没有副作用的方法,或者其副作用是只变异"this")。
我添加了这个注解,我把它添加到所有相关的jOOQ API中,这是一个有点像牦牛剃头的过程(https://github.com/jOOQ/jOOQ/commit/f2b529a2305f8c5f8d037776687887a5acd50b11),然后就看到了


正如你所看到的,现在IntelliJ在用户忘记消耗jOOQ的任何DSL方法的结果时都会发出警告(通过调用execute() ,将其传递给一些消耗它的方法,等等)。