编译时验证
适用于 ✅ 开源版 ✅ 专业版 ✅ 企业版
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、夜间构建等中,该框架确实可以很好地工作。
反馈
您对此页面有任何反馈吗? 我们很乐意听到它!