从纯Java生成jOOQ类

时间:2015-06-29 21:58:17

标签: java code-generation database-schema ddl jooq

有没有办法从纯Java代码生成jOOQ类?如果没有,最接近的替代方案是什么?理想情况下,我想在gradle构建中执行此操作。

我找到this answer,其链接到this blog post。这篇文章的精髓是:

  1. 以JPA模型
  2. 开头
  3. 将其转换为DDL脚本(.sql文件中包含CREATE个语句)
  4. 创建一个新的HSQLDB文件,并通过在其上运行该DDL脚本来填充表。将生成的数据库保存到磁盘。
  5. 从磁盘加载该数据库并在其上运行jOOQ代码生成
  6. 使用生成的生成的jOOQ类。
  7. 对于这种方法,有三件事让我烦恼:

    • 该博客文章在Maven(& Ant)中完成所有工作。我想使用Gradle,但我可以解决这个问题。
    • 我必须从JPA开始。我更喜欢从我的架构的纯jOOQ定义开始。 jOOQ是否有模式定义DSL / API?
    • 不需要中间步骤(DDL脚本和HSQLDB创建)作为最终产品。相反,他们只需要将JPA模型转换为jOOQ理解为输入的东西。应该有一个更整洁(仅限Java)的方式,即使jOOQ没有自己的架构定义API。有吗?

2 个答案:

答案 0 :(得分:4)

Jooq需要事先创建一些表格。你可以使用Flyway(你也应该使用它的迁移)。

拥有所有表后,您可以使用此代码段让Jooq为您的表生成源文件:

import org.jooq.util.GenerationTool;
import org.jooq.util.jaxb.*;

Configuration configuration = new Configuration()
    .withJdbc(new Jdbc()
        .withDriver("org.postgresql.Driver")
        .withUrl("jdbc:postgresql://localhost/your_database")
        .withUser("username")
        .withPassword("password"))
    .withGenerator(new Generator()
        .withName("org.jooq.util.DefaultGenerator")
        .withDatabase(new Database()
                .withName("org.jooq.util.postgres.PostgresDatabase")
                .withIncludes(".*")
                .withSchemata(new Schema().withInputSchema("your_schema"))
        )
        .withTarget(new Target()
            .withPackageName("jooq.generate")
            .withDirectory("src/main/java")));
try {
  GenerationTool.generate(configuration);
} catch (Exception e) {
  e.printStackTrace();
}

这会在.java上留下一些src/main/java path个文件。使用您的数据库设置等配置代码段

这大致就是我们在工作中的工作方式。 Jooq和Flyway的表现很好。您可以查看Jooq关于Code generation

的文档

我们没有使用maven的插件,因为我们有一个多租户设置,需要在数据库迁移和代码生成方面进行一些运行时配置。

我想,一旦你在某个类的静态main方法中准备了你的Jooq代,你就可以从gradle任务中运行它。我只能向您指出Jooq关于从gradle运行它的文档here

编辑:在好奇心看了一下文档和我自己生成的代码后,我看到您可以扩展RecordTableImpl<Record>类来生成手动创建的架构类。

您可以在RecordTable类上看到here重要部分的一小部分示例摘要。

无论如何,考虑到Jooq(和Flyway)并不希望你避免使用SQL,而是接受它。正常的做事方式是

  1. 使用SQL脚本创建数据库对象
  2. 使用Jooq生成器生成架构类
  3. 你在Jooq的DSL环境中使用它们。

答案 1 :(得分:2)

基于@ ggalmazor的answer,我最终使用的是Java代码,其中包含最少的SQL脚本核心。现在我的代码生成过程包含3个简单的步骤:

  1. 编写SQL DDL脚本(即CREATE TABLE语句)
  2. 运行Flyway,创建H2内存数据库。
  3. 在同一个数据库上运行jOOQ以生成Java代码。
  4. Flyway和jOOQ都是用Java代码完全配置的;不需要xml配置文件。

    这是我的代码:

    public class Main {
    
        public static void main(String... args) {
            JdbcDataSource ds = new JdbcDataSource();
            ds.setURL("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1");
            ds.setUser("u");
            ds.setPassword("p");
    
            // Flyway
            Flyway flyway = new Flyway();
            flyway.setDataSource(ds);
            flyway.setLocations("classpath:com.example.datadefinition.flyway.migrations");
            flyway.migrate();
    
            // jOOQ
            try (Connection c = ds.getConnection()) {
                Configuration configuration = new Configuration()
                    .withGenerator(new Generator()
                        .withName(MyOwnGenerator.class.getCanonicalName())
                        .withDatabase(new Database()
                            .withName(H2Database.class.getCanonicalName())
                            .withIncludes(".*")
                            .withExcludes("")
                            .withInputSchema("PUBLIC")
                        )
                        .withTarget(new Target()
                            .withPackageName("com.example.lib.data")
                            // jOOQ will create package folders for com.example.lib.data
                            .withDirectory("../sibling-project/src/main")
                        )
                    );
    
                GenerationTool tool = new GenerationTool();
                tool.setConnection(c);
                tool.run(configuration);
            } catch (SQLException e) {
                // sql connection problems
                e.printStackTrace();
            } catch (Exception e) {
                // run failed
                e.printStackTrace();
            }
        }
    }
    
    public class MyOwnGenerator extends JavaGenerator {
    
        public SwsGenerator() {
            setStrategy(new MyOwnGeneratorStrategy());
        }
    
    }
    
    public class MyOwnGeneratorStrategy extends DefaultGeneratorStrategy {
    
    }