将 JooQ 与 SQL Server 一起使用,getTables() 方法返回服务器上所有数据库中的所有表

Posted

技术标签:

【中文标题】将 JooQ 与 SQL Server 一起使用,getTables() 方法返回服务器上所有数据库中的所有表【英文标题】:Using JooQ with SQL Server, getTables() method is returning all tables across all DB's on server 【发布时间】:2020-11-20 14:22:12 【问题描述】:

当在 Jooq 中使用 DSLContext.meta().getTables() 方法返回数据库上的表列表时,它在 postgres 和 H2 服务器上完美运行。但是,当在 SQL Server 数据库上进行相同的调用时,它最终会返回服务器上所有 db 上的每个表,而不仅仅是数据源 db。

所以说在这个例子中,服务器上有 2 个 db,DB1 有 2 个表,DB2 有 3 个表。如果我只想使用 DSLContext.meta().getTables() 返回 DB1 中的 2 个表,它会在 postgres 和 H2 上正确返回这 2 个表,但是当在 SQL Server 上它返回所有 5 个具有相同代码的表时,唯一的区别是数据源。

在将 Jooq 与 SQL Server 结合使用时,有没有办法只返回特定数据库的表?行为是错误还是故意的,我应该为 SQL Server dbs 做一些不同的事情?

如果有兴趣,这里是使用它的方法:

private boolean isTableExists(String table_name)
        boolean isTable = false;
        List<Table<?>> tables = dsl.meta().getTables(); //this is the problem line, returning the wrong number of tables on SQL Server
        for (Table<?> table : tables)
            if (table.getName().equals(table_name))
                isTable = true;
                break;
            
        
        return isTable;
    

注意:我没有使用任何生成的代码,我使用的是 jooq 3.14.4 的试用版。我只使用 Jooq 大约 2 周。

【问题讨论】:

【参考方案1】:

jOOQ 的DSLContext.meta() API 根据 jOOQ 3.13 为所有目录和所有模式生成表。因此,您必须添加一些逻辑来跳过不需要的数据库,例如像这样:

private boolean isTableExists(String tableName) 
    return dsl.meta()
       .getCatalogs()
       .stream()
       .filter(c -> c.getName().equals("databaseName"))
       .flatMap(c -> c.getSchemas().stream())
       .filter(s -> s.getName().equals("schemaName"))
       .flatMap(s -> s.getTables().stream())
       .anyMatch(t -> t.getName().equals(tableName));

在 jOOQ 3.14(参见 #10204)中,将有额外的 API 在访问元信息之前过滤掉不需要的对象。这具有相同的效果,但可能更快,例如

private boolean isTableExists(String tableName) 
    return !dsl.meta()
       .filterCatalogs(c -> c.getName().equals("databaseName"))
       .filterSchemas(s -> s.getName().equals("schemaName"))
       .filterTables(t -> t.getName().equals(tableName))
       .getTables()
       .isEmpty();

【讨论】:

以上是关于将 JooQ 与 SQL Server 一起使用,getTables() 方法返回服务器上所有数据库中的所有表的主要内容,如果未能解决你的问题,请参考以下文章

Jooq 与 SQL Server 如何选择前 N 个结果

将 UNNEST 与 jOOQ 一起使用

SQL Server 2017 - 使用 Gradle 生成 JOOQ 代码

如何修复:Jooq 代码不会从 sql 脚本为内存 db 中的 sqlite 生成 java 代码

带有准备好的语句的 Java JOOQ

Information_schema 未从 jooq for SQL Server 生成