温州手机网站制作,江门网站建设易搜互联,上海申远装饰公司官网,珠宝购物网站的建设Java 8引入了JSR-308#xff0c;它为Java语言添加了新的注释功能。 最重要的是#xff1a;键入注释。 现在可以像下面这样设计怪物了#xff1a; 比注解更疯狂的是类型注解。 在数组上。 谁认为这是有效的Java代码#xff1f; pic.twitter.com/M9fSRRerAD — Lukas Eder它为Java语言添加了新的注释功能。 最重要的是键入注释。 现在可以像下面这样设计怪物了 比注解更疯狂的是类型注解。 在数组上。 谁认为这是有效的Java代码 pic.twitter.com/M9fSRRerAD — Lukas Ederlukaseder 2016年3月20日 该推文中显示的代码确实可以编译。 现在可以注释每种类型以便以任何自定义方式增强类型系统。 为什么你可能会问 这种语言增强的主要驱动用例之一是checker框架 这是一个开放源代码库可让您轻松实现任意编译器插件以进行复杂的类型检查。 最无聊和琐碎的例子是可空性。 考虑以下代码 import org.checkerframework.checker.nullness.qual.Nullable;class YourClassNameHere {void foo(Object nn, Nullable Object nbl) {nn.toString(); // OKnbl.toString(); // Failif (nbl ! null)nbl.toString(); // OK again}
} 上面的示例可以直接在checker框架实时演示控制台中运行 。 使用以下注释处理器编译以上代码 javac -processor org.checkerframework.checker.nullness.NullnessChecker afile.java 产量 错误[dereference.of.nullable]取消引用可能为空的引用nbl59 太棒了 例如它的工作方式与在Ceylon或Kotlin中 实现的流敏感类型非常相似不同之处在于它更为冗长。 但是它也要强大得多因为可以使用注释处理器直接在Java中实现实现增强的和带注释的Java类型系统的规则 通过某种方式使注解图灵完整。55357;56841; 这对jOOQ有什么帮助 jOOQ已经提供了两种类型的API文档注释。 这些注释是 PlainSQL –表示DSL方法接受“纯SQL”字符串这可能会带来SQL注入风险 Support –表示DSL方法可以本机工作或者可以针对给定的SQLDialect集进行仿真 这种方法的一个示例是CONNECT BY子句 该子句得到CubridInformix和Oracle的支持为了方便起见它也被重载为也接受“普通SQL”谓词 Support({ CUBRID, INFORMIX, ORACLE })
PlainSQL
SelectConnectByConditionStepR connectBy(String sql); 到目前为止这些注释仅用于文档目的。 使用jOOQ 3.9后不再可用。 现在我们向jOOQ API引入了两个新的注释 org.jooq.Allow –允许在给定范围内使用一组方言或PlainSQL批注 org.jooq.Require –在给定范围内要求通过Support注释支持一组方言 最好通过示例来解释。 让我们先看看PlainSQL 限制对 使用jOOQ API的最大优点之一就是SQL注入已经成为过去。 由于jOOQ是内部特定于域的语言因此用户确实可以直接在Java代码中直接定义SQL表达式树而不是像JDBC那样使用声明的字符串化版本。 表达式树是用Java编译的因此不可能通过用户输入注入任何不需要的或无法预见的表达式。 但是有一个例外。 jOOQ并不支持每个数据库中的所有SQL功能。 这就是jOOQ附带丰富的“普通SQL” API的原因在该API中可以将自定义SQL字符串嵌入SQL表达式树中的任何位置。 例如上面的CONNECT BY子句 DSL.using(configuration).select(level()).connectBy(level ?, bindValue).fetch(); 上面的jOOQ查询转换为以下SQL查询 SELECT level
FROM dual
CONNECT BY level ? 如您所见完全有可能“做错”并产生SQL注入风险就像在JDBC中一样 DSL.using(configuration).select(level()).connectBy(level bindValue).fetch(); 区别非常细微。 使用jOOQ 3.9和checker框架现在可以指定以下Maven编译器配置 pluginartifactIdmaven-compiler-plugin/artifactIdversion3.3/versionconfigurationsource1.8/sourcetarget1.8/targetforktrue/forkannotationProcessorsannotationProcessororg.jooq.checker.PlainSQLChecker/annotationProcessor/annotationProcessorscompilerArgsarg-Xbootclasspath/p:1.8/arg/compilerArgs/configuration
/plugin org.jooq.checker.PlainSQLChecker将确保不会编译使用带有PlainSQL注释的API的客户端代码。 我们收到的错误消息是这样的 C\ Users \ lukas \ workspace \ jOOQ \ jOOQ-examples \ jOOQ-checker-framework-example \ src \ main \ java \ org \ jooq \ example \ checker \ PlainSQLCheckerTests.java[17,17]错误[普通]当前范围不允许使用SQL。 使用 Allow.PlainSQL。] 如果您知道自己在做什么并且绝对必须在非常特定的位置范围使用jOOQ的PlainSQL API则可以使用Allow.PlainSQL对该位置范围进行注释并且代码可以再次正常编译 // Scope: Single method.
Allow.PlainSQL
public ListInteger iKnowWhatImDoing() {return DSL.using(configuration).select(level()).connectBy(level ?, bindValue).fetch(0, int.class);
} 甚至 // Scope: Entire class.
Allow.PlainSQL
public class IKnowWhatImDoing {public ListInteger iKnowWhatImDoing() {return DSL.using(configuration).select(level()).connectBy(level ?, bindValue).fetch(0, int.class);}
} 甚至但是您可能只是关闭检查器 // Scope: entire package (put in package-info.java)
Allow.PlainSQL
package org.jooq.example.checker; 好处是显而易见的。 如果安全性对您非常重要应该如此则只需在每个开发人员版本或至少在CI版本中启用org.jooq.checker.PlainSQLChecker 并在“偶然”使用PlainSQL API时获得编译错误遇到。 限制对 现在对于大多数用户而言更有趣的是能够检查客户端代码中使用的jOOQ API是否确实支持您的数据库。 例如上面的CONNECT BY子句仅在Oracle中受支持如果我们忽略不太流行的Cubrid和Informix数据库。 假设您仅使用Oracle。 您要确保您使用的所有jOOQ API都与Oracle兼容。 现在您可以将以下注释添加到所有使用jOOQ API的软件包中 // Scope: entire package (put in package-info.java)
Allow(ORACLE)
package org.jooq.example.checker; 现在只需激活org.jooq.checker.SQLDialectChecker来键入代码以检查Allow符合性即可完成 pluginartifactIdmaven-compiler-plugin/artifactIdversion3.3/versionconfigurationsource1.8/sourcetarget1.8/targetforktrue/forkannotationProcessorsannotationProcessororg.jooq.checker.SQLDialectChecker/annotationProcessor/annotationProcessorscompilerArgsarg-Xbootclasspath/p:1.8/arg/compilerArgs/configuration
/plugin 从现在开始每当您使用任何jOOQ API时上述检查器都将验证以下三个值是否为true 正在使用的jOOQ API未使用Support注释 使用的jOOQ API带有Support注释但没有任何显式的SQLDialect 即“可在所有数据库上工作”例如DSLContext.select() 使用的jOOQ API带有Support注释并带有SQLDialects引用的至少一个Allow 因此在这样标注的包装中…… // Scope: entire package (put in package-info.java)
Allow(ORACLE)
package org.jooq.example.checker; ……使用这样注释的方法就可以了 Support({ CUBRID, INFORMIX, ORACLE })
PlainSQL
SelectConnectByConditionStepR connectBy(String sql); …但是使用这样注释的方法不是 Support({ MARIADB, MYSQL, POSTGRES })
SelectOptionStepR forShare(); 为了允许使用此方法例如客户端代码除了可以使用ORACLE语言外还可以使用MYSQL语言 // Scope: entire package (put in package-info.java)
Allow({ MYSQL, ORACLE })
package org.jooq.example.checker; 从现在开始此程序包中的所有代码都可能引用支持MySQL和/或Oracle的方法。 Allow批注有助于在全局级别上访问API。 多个Allow注释范围可能不同创建了允许的方言的Allow取关系如下所示 // Scope: class
Allow(MYSQL)
class MySQLAllowed {Allow(ORACLE)void mySQLAndOracleAllowed() {DSL.using(configuration).select()// Works, because Oracle is allowed.connectBy(...)// Works, because MySQL is allowed.forShare();}
} 从上面可以看出析取两个方言不能确保给定的语句在两个数据库中都可以使用。 所以… 如果我希望同时支持两个数据库怎么办 在这种情况下我们将使用新的Require注释。 多个Require注释范围可能不同创建所需方言的合集如下所示 // Scope: class
Allow
Require({ MYSQL, ORACLE })
class MySQLAndOracleRequired {Require(ORACLE)void onlyOracleRequired() {DSL.using(configuration).select()// Works, because only Oracle is required.connectBy(...)// Doesnt work because Oracle is required.forShare();}
}如何使用 假设您的应用程序仅需要与Oracle一起使用。 现在您可以在软件包上添加以下注释例如由于在您的代码中不允许将MySQL作为方言因此您将无法使用任何仅MySQL的API Allow(ORACLE)
package org.jooq.example.checker; 现在随着需求的变化您还希望从应用程序中也开始支持MySQL。 只需将软件包规格更改为以下内容然后开始修复jOOQ使用中的所有编译错误。 // Both dialects are allowed, no others are
Allow({ MYSQL, ORACLE })// Both dialects are also required on each clause
Require({ MYSQL, ORACLE })
package org.jooq.example.checker;默认值 默认情况下对于任何范围 org.jooq.checker.SQLDialectChecker都采用以下注释 什么都不允许。 每个Allow批注都会添加到允许的方言集中。 一切都是必需的。 每个Require批注将从必填方言集中删除。 实际观看 这些功能将是jOOQ 3.9的组成部分。 只需添加以下依赖项即可使用它们 dependency!-- Use org.jooq for the Open Source editionorg.jooq.pro for commercial editions, org.jooq.pro-java-6 for commercial editions with Java 6 support,org.jooq.trial for the free trial edition --groupIdorg.jooq/groupIdartifactIdjooq-checker/artifactIdversion${org.jooq.version}/version
/dependency …然后为您的编译器插件选择适当的注释处理器。 不能等到jOOQ 3.9吗 不用了 只需从GitHub上检查3.9.0-SNAPSHOT版本然后按照此处给出的示例项目进行操作 https://github.com/jOOQ/jOOQ/tree/master/jOOQ-examples/jOOQ-checker-framework-example 做完了 从现在开始使用jOOQ时您可以确保编写的任何代码都可以在计划支持的所有数据库上运行 我认为今年的Annotatiomaniac冠军头衔应该交给检查框架的制定者 有关检查器框架的更多信息 http://types.cs.washington.edu/checker-framework/ http://eisop.uwaterloo.ca/live#modedisplay实时演示 翻译自: https://www.javacodegeeks.com/2016/05/jsr-308-checker-framework-add-even-typesafety-jooq-3-9.html