简体   繁体   English

jOOQ如何根据配置处理多个数据库引擎

[英]How can jOOQ be used to deal with multiple database engine depending on configuration

I'm an experienced and happy jOOQ user.我是一个经验丰富且快乐的 jOOQ 用户。

I'm now working on a project that need to support multiple database engines (PostgreSQL, MySQL, Oracle at least).我现在正在开发一个需要支持多个数据库引擎的项目(至少 PostgreSQL、MySQL、Oracle)。

We want something with the low level enough to have control on our queries.我们想要足够低级别的东西来控制我们的查询。 JPA/Hibernate are too high level for us. JPA/Hibernate 对我们来说太高级了。

I know jOOQ works with a metamodel, and that metamodel is generated from the database schema.我知道 jOOQ 使用元模型,并且该元模型是从数据库模式生成的。

Is there any way to reuse the same jOOQ query definitions against different database engines (with the same schema, apart from engine specific differences)?有没有办法针对不同的数据库引擎重用相同的 jOOQ 查询定义(具有相同的模式,除了引擎特定的差异)?

Fine if we need to recompile the java classes if necessary.如果我们需要在必要时重新编译 java 类,那很好。 Compile time configuration is fine for us.编译时配置对我们来说很好。

jOOQ has been designed for this. jOOQ 就是为此而设计的。 You need to do these things:你需要做这些事情:

  1. Have a Configuration with a SQLDialect ready depending on your JDBC connection.根据您的 JDBC 连接,准备好带有SQLDialectConfiguration That's the easy part.那是容易的部分。 That Configuration will automatically generate vendor specific SQL for all of your jOOQ queries.Configuration将为您的所有 jOOQ 查询自动生成特定于供应商的 SQL。 This can be done at runtime.这可以在运行时完成。 No need for any compile time adaptations.无需任何编译时间调整。
  2. Make sure your tables / columns always use the same case, or turn off quoting in jOOQ's identifiers for case insensitive behaviour (depending on your MySQL configuration, that might not be enough, see the MySQL manual ).确保您的表/列始终使用相同的大小写, 或关闭 jOOQ 标识符中不区分大小写的行为的引用(取决于您的 MySQL 配置,这可能还不够, 请参阅 MySQL 手册)。 You can then re-use the generated code from any of your database dialects on all the other dialects.然后,您可以在所有其他方言上重新使用从任何数据库方言生成的代码。
  3. Make sure you only use jOOQ API that is annotated with @Support({ MYSQL, ORACLE, POSTGRES }) .确保只使用带有@Support({ MYSQL, ORACLE, POSTGRES })注释的 jOOQ API。 For example, DSL.toDate() cannot be used, because it doesn't support MySQL, but DSL.trunc() can be used, because all 3 target dialects are present.例如,不能使用DSL.toDate() ,因为它不支持 MySQL,但可以使用DSL.trunc() ,因为所有 3 个目标方言都存在。

We're increasingly also adding dialect specific information to the jOOQ manual, eg for the SHL() function :我们也越来越多地在 jOOQ 手册中添加方言特定信息,例如SHL() function

-- ASE, HSQLDB, SQLDATAWAREHOUSE, SQLSERVER, SYBASE
(1 * CAST(power(2, 4) AS int))

-- AURORA_MYSQL, AURORA_POSTGRES, COCKROACHDB, CUBRID, MARIADB, MEMSQL, MYSQL, POSTGRES, SQLITE, VERTICA
(1 << 4)

-- DB2, INFORMIX
(1 * CAST(power(2, 4) AS integer))

-- FIREBIRD
bin_shl(1, 4)

-- H2
lshift(1, 4)

-- ORACLE
(1 * CAST(power(2, 4) AS number(10)))

-- TERADATA
shiftleft(1, 4)

-- ACCESS, DERBY, HANA, INGRES, REDSHIFT
/* UNSUPPORTED */

In order to ensure you're not accidentally writing a query that doesn't work on some dialect, you can:为了确保您不会意外编写不适用于某些方言的查询,您可以:

  1. Run integration tests eg using testcontainers on each target dialect运行集成测试,例如在每个目标方言上使用testcontainers
  2. UsejOOQ's Checker Framework or ErrorProne integration for static code analysis.使用jOOQ 的 Checker Framework 或 ErrorProne 集成进行 static 代码分析。 See also this blog post here . 另请参阅此处的此博客文章

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM