【问题标题】:Generate jOOQ classes from pure Java从纯 Java 生成 jOOQ 类
【发布时间】:2015-09-16 13:00:41
【问题描述】:

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

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

  1. 从 JPA 模型开始
  2. 将其转换为 DDL 脚本(包含 CREATE 语句的 .sql 文件)
  3. 创建一个新的 HSQLDB 文件,并通过在其上运行 DDL 脚本来填充表。将生成的数据库保存到磁盘。
  4. 从磁盘加载该数据库并在其上运行 jOOQ 代码生成
  5. 使用生成的 jOOQ 类。

这种方法有三点让我烦恼:

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

【问题讨论】:

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


    【解决方案1】:

    Jooq 需要事先创建一些表。您可以为此使用 Flyway(并且您也应该使用它的迁移)。

    一旦你有了所有的表,你可以使用这个 sn-p 让 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();
    }
    

    这将在src/main/java path 上留下一些.java 文件。使用您的数据库设置等配置 sn-p。

    这大致就是我们在工作项目中做事的方式。 Jooq 与Flyway 配合得非常好。你可以查看 Jooq 关于Code generation 的文档。

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

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

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

    你可以看到here 一个小例子sn-p 对RecordTable 类的重要部分。

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

    1. 您使用 SQL 脚本创建数据库对象
    2. 您使用 Jooq 生成器生成架构类
    3. 您可以将它们与 Jooq 的 DSL 上下文一起使用。

    【讨论】:

      【解决方案2】:

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

      1. 编写 SQL DDL 脚本(即CREATE TABLE 语句)
      2. 运行 Flyway,创建 H2 内存数据库。
      3. 在同一个数据库上运行 jOOQ 以生成 Java 代码。

      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 {
      
      }
      

      【讨论】:

        猜你喜欢
        • 2019-10-10
        • 2019-01-08
        • 2021-12-29
        • 2021-01-27
        • 2021-01-22
        • 1970-01-01
        • 2017-07-12
        • 2017-08-15
        • 2018-03-07
        相关资源
        最近更新 更多