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

问题描述

当在 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 周。

标签: javasql-serverjooq

解决方案


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();
}

推荐阅读