编译时验证
适用于 ✅ 开源版 ✅ 专业版 ✅ 企业版
Java 8 引入了 JSR 308(类型注解),随之诞生了 Checker Framework。 Checker Framework 允许实现编译器插件,这些插件可以对您的 Java AST 运行复杂的检查,以引入丰富的基于注解的类型语义,例如:
// This still compiles @Positive int value1 = 1; // This no longer compiles: @Positive int value2 = -1;
jOOQ 有两个对于 Checker Framework 进行类型检查非常有趣的注解,即
-
org.jooq.Support
:此注解使用有关哪个数据库支持给定的 SQL 子句或函数等有价值的信息来记录 jOOQ DSL API。 例如,目前只有 Informix 和 Oracle 支持 CONNECT BY 子句。 -
org.jooq.PlainSQL
:此注解记录在 plain SQL 上运行的 jOOQ DSL API。 Plain SQL 是基于字符串的 SQL,它被注入到 jOOQ 表达式树中,如果用户不小心,这些 API 元素会引入一定的 SQL 注入风险(就像一般的 JDBC 一样)。
使用可选的 jooq-checker
模块(仅可从 Maven Central 获得),用户现在可以对其代码进行类型检查,使其仅适用于给定的方言集,或禁止访问 plain SQL。
示例
一篇详细的博客文章展示了这是如何深入工作的。 通过向您的 Maven 构建添加一个简单的依赖项
<dependency> <!-- Use org.jooq for the Open Source Edition org.jooq.pro for commercial editions with Java 21 support, org.jooq.pro-java-17 for commercial editions with Java 17 support, org.jooq.pro-java-11 for commercial editions with Java 11 support, org.jooq.pro-java-8 for commercial editions with Java 8 support, org.jooq.trial for the free trial edition with Java 21 support, org.jooq.trial-java-17 for the free trial edition with Java 17 support, org.jooq.trial-java-11 for the free trial edition with Java 11 support, org.jooq.trial-java-8 for the free trial edition with Java 8 support Note: Only the Open Source Edition is hosted on Maven Central. Install the others locally using the provided scripts, or access them from here: https://repo.jooq.org See the JDK version support matrix here: https://jooq.org.cn/download/support-matrix-jdk --> <groupId>org.jooq</groupId> <artifactId>jooq-checker</artifactId> <version>3.20.5</version> </dependency>
dependencies { // Use org.jooq for the Open Source Edition // org.jooq.pro for commercial editions with Java 21 support, // org.jooq.pro-java-17 for commercial editions with Java 17 support, // org.jooq.pro-java-11 for commercial editions with Java 11 support, // org.jooq.pro-java-8 for commercial editions with Java 8 support, // org.jooq.trial for the free trial edition with Java 21 support, // org.jooq.trial-java-17 for the free trial edition with Java 17 support, // org.jooq.trial-java-11 for the free trial edition with Java 11 support, // org.jooq.trial-java-8 for the free trial edition with Java 8 support // // Note: Only the Open Source Edition is hosted on Maven Central. // Install the others locally using the provided scripts, or access them from here: https://repo.jooq.org // See the JDK version support matrix here: https://jooq.org.cn/download/support-matrix-jdk implementation("org.jooq:jooq-checker:3.20.5") }
dependencies { // Use org.jooq for the Open Source Edition // org.jooq.pro for commercial editions with Java 21 support, // org.jooq.pro-java-17 for commercial editions with Java 17 support, // org.jooq.pro-java-11 for commercial editions with Java 11 support, // org.jooq.pro-java-8 for commercial editions with Java 8 support, // org.jooq.trial for the free trial edition with Java 21 support, // org.jooq.trial-java-17 for the free trial edition with Java 17 support, // org.jooq.trial-java-11 for the free trial edition with Java 11 support, // org.jooq.trial-java-8 for the free trial edition with Java 8 support // // Note: Only the Open Source Edition is hosted on Maven Central. // Install the others locally using the provided scripts, or access them from here: https://repo.jooq.org // See the JDK version support matrix here: https://jooq.org.cn/download/support-matrix-jdk implementation "org.jooq:jooq-checker:3.20.5" }
... 您现在可以包含以下两个检查器之一
SQLDialectChecker
SQLDialect 检查器读取您的源代码中的所有 org.jooq.Allow
和 org.jooq.Require
注解,并检查您正在使用的 jOOQ API 在给定的上下文中是否允许和/或需要,其中该上下文可以是任何范围,包括
- 一个包
- 一个类
- 一个方法
配置此编译器插件
<plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.3</version> <configuration> <source>1.8</source> <target>1.8</target> <fork>true</fork> <annotationProcessors> <annotationProcessor>org.jooq.checker.SQLDialectChecker</annotationProcessor> </annotationProcessors> <compilerArgs> <arg>-Xbootclasspath/p:1.8</arg> <!-- Optionally, provide a default allowed dialect --> <arg>-J-Dorg.jooq.checker.dialects.allow=H2</arg> <!-- And/or a default required dialect --> <arg>-J-Dorg.jooq.checker.dialects.require=H2</arg> </compilerArgs> </configuration> </plugin>
... 注解您的包,例如
// Scope: entire package (put in package-info.java) @Allow(ORACLE) package org.jooq.example.checker;
现在,您将不再能够使用 Oracle 中不可用的任何 SQL Server 特定的功能。 太棒了!
当您嵌套这些注解时,会有很多微妙的规则起作用。 请参阅这篇博客文章了解详细信息。
PlainSQLChecker
这个检查器要简单得多。 只需添加以下编译器插件即可默认停用 plain SQL 的使用
<plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.3</version> <configuration> <source>1.8</source> <target>1.8</target> <fork>true</fork> <annotationProcessors> <annotationProcessor>org.jooq.checker.PlainSQLChecker</annotationProcessor> </annotationProcessors> <compilerArgs> <arg>-Xbootclasspath/p:1.8</arg> </compilerArgs> </configuration> </plugin>
从现在开始,您不再会在 jOOQ 代码中冒任何 SQL 注入的风险,因为您的编译器会拒绝所有此类 API 的使用。 但是,如果您需要在给定的包/类/方法上放置异常,只需添加 org.jooq.Allow.PlainSQL
注解,如下所示
// Scope: Single method. @Allow.PlainSQL public List<Integer> iKnowWhatImDoing() { return DSL.using(configuration) .select(level()) .connectBy("level < ?", bindValue) .fetch(0, int.class); }
从编译速度来看,Checker Framework确实增加了一些显着的开销,并且其 IDE 工具尚未达到可以将此类检查馈送到 IDE 以获得真正的用户反馈的水平,但是如果您将其集成到 CI、夜间构建等中,该框架确实可以很好地工作。
反馈
您对此页面有任何反馈吗? 我们很乐意听到它!