JDBC API getTables()、getColumns() 中,通配符进行转义的问题

在我的 使用 JDBC API 获取 Mysql 的 表字段 时,返回为空 的解决方案 这篇Blog中,提及到了如何使用 JDBC API 来获取 column 的信息。

但是,当时没有讲到一个注意点,现在补充一下。

getColumns() 这个API中,它的4个参数的注释如下:

  • catalog - a catalog name; must match the catalog name as it is stored in the database; “” retrieves those without a catalog; null means that the catalog name should not be used to narrow the search

  • schemaPattern - a schema name pattern; must match the schema name as it is stored in the database; “” retrieves those without a schema; null means that the schema name should not be used to narrow the search

  • tableNamePattern - a table name pattern; must match the table name as it is stored in the database

  • columnNamePattern - a column name pattern; must match the column name as it is stored in the database

可以看到,后3个参数都是 pattern ,也就是说,这几个参数是支持通配符,即 支持 %_ 来进行模糊匹配的。

所以,假设有如下的代码:

ResultSet colRet = dbMetaData.getColumns(null, "my%test", "tab002", "%");

那么,当你的数据库中,有 mytestmy_testmy1testmy23test 这些 schema 时,而这些 schema 中以恰巧都有一个名叫 tab002 的表时,那么,这些表中的这所有字段将会全部被返回。因为, % 是匹配任意多的字符的。

那么,问题来了?该如何对 %_ 进行转义呢?

有些人会说,这还不简单么,直接用 ** 进行转义啊。

对,我一开始也是这么想的,但是事实总是残忍的。如果你当前使用的是 Oracle ,那么,很不幸的是,你这么做会导致你可能获取不到任何 column。

这是为什么呢?因为每个 数据库 提供商,他们在实现 JDBC 时,给定的转义符是不一样的,有的是 **,有的是 “\”。

那这咋整呢?不用急,细细找总是会有办法的。

果不其然,在 DatabaseMetaData 类中,提供了一个方法来获取转义字符,它就是 getSearchStringEscape()。所以,我们只需要对 schematable 作如下的转义就可以了:

Connection connection = DriverManager.getConnection(jdbc_url, userName, password);

DatabaseMetaData dbMetaData = connection.getMetaData();

String escape = dbMetaData.getSearchStringEscape();

schema = schema.replace("_", (escape + "_"));
table = table.replace("%", (escape + "%"));

ResultSet colRet = dbMetaData.getColumns(null, schema, table, "%");

补充说明

  • 虽然 catalog 这个参数没有声明是一个 pattern,但是通过对 mysql 的实验,其实它也是支持 pattern 的,所以,为了保险起见,我们最好对 catalogschematable 都做一个转义。

  • getTable() 这个API也需要一样的处理。

  • 如有必要, getSchemas() 也需要同样的处理。

你可能感兴趣的:(db,Java)