简体   繁体   中英

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

I'm an experienced and happy jOOQ user.

I'm now working on a project that need to support multiple database engines (PostgreSQL, MySQL, Oracle at least).

We want something with the low level enough to have control on our queries. JPA/Hibernate are too high level for us.

I know jOOQ works with a metamodel, and that metamodel is generated from the database schema.

Is there any way to reuse the same jOOQ query definitions against different database engines (with the same schema, apart from engine specific differences)?

Fine if we need to recompile the java classes if necessary. Compile time configuration is fine for us.

jOOQ has been designed for this. You need to do these things:

  1. Have a Configuration with a SQLDialect ready depending on your JDBC connection. That's the easy part. That Configuration will automatically generate vendor specific SQL for all of your jOOQ queries. 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 ). 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 }) . 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.

We're increasingly also adding dialect specific information to the jOOQ manual, eg for the 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
  2. UsejOOQ's Checker Framework or ErrorProne integration for static code analysis. See also this blog post here .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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