不要忘記在jOOQ中呼叫.execute()

語言: CN / TW / HK

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() 或類似的東西,我們就不會得到任何結果,而我們想要這些結果,就像呼叫StringBuilderStream 。但我們不想要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),然後就看到了

imageimage

正如你所看到的,現在IntelliJ在使用者忘記消耗jOOQ的任何DSL方法的結果時都會發出警告(通過呼叫execute() ,將其傳遞給一些消耗它的方法,等等)。