从ResultSet Java获取主键列

时间:2014-01-24 08:59:35

标签: java mysql sql database resultset

我正在尝试从ResultSet获取表的主键列。以下是步骤

我跟着:

1. SQL QUERY: Select id,subid,email,empname from Employee
2. Executed this from java.sql.Statement and got the Results in ResultSet.

这是有趣的部分。

3. ResultSetMetadata rsmd = rs.getMetadata();

现在,如果我观察此变量“ rsmd ”,它会显示相关列名的主键标记,但我无法访问它或将其置于任何变量中。

我需要帮助。

注意:我不想使用DatabaseMetadata及其getPrimaryKeys()函数,因为它会对外部数据库产生额外的影响。此外,ResultSetMetadata对象已经具有我只需要获取的主键信息。

4 个答案:

答案 0 :(得分:6)

关于您的问题和解决方案的一些想法(希望有用):

在使用结果集元数据中具有主键信息的结果集时,我的生活经历并没有发生。

在我看来甚至很奇怪,因为在原则上,结果集不仅限于显示仅在一个表的列中组织的行,并且不强制显示一个表的所有列,甚至列也可​​能不是表列。

例如,我们可能会发出类似

的查询
select X.a, X.b, Y.n, Y.m, 'bla'||X.c||'blub'||Y.l from X, Y;

在这种情况下,我们可能有或没有来自一个或两个表的主列,也可能没有。

如您所知,标准ResultSetMetaData - 接口不提供主键信息访问。您在调试器中看到的是实现该接口的类的实例。

有几种方法可以处理您的任务:

  1. (不是我喜欢的方式)
    转换为具体实现ResultSetMetaData - 类和访问权限 主要密钥信息,如果可用。但要注意不是每一个 ResultSetMetaData实施提供了此信息。

  2. (更多的建筑方法,也没有从我这边提出,但需要
    如果我们处理一个不完整的JDBC驱动程序)  利用您使用的不同数据库的系统表 但当然是在抽象中隐藏它,例如桥梁模式。 根据拨款,您通常没有什么大不了的 (包括测试基础架构部分最多4个人工作日和大约1个人日 您要访问的每个数据库系统) 然后,您可以从中获得任何所需的元数据信息,包括外键关系。

  3. (我做什么)
    只需使用java.sql.DatabaseMetaData - 类 它为每个可访问的表提供了所需的主键信息。

  4. 这是一个代码片段(在Java 7中):

      public static Set<String> getPrimaryKeyColumnsForTable(Connection connection, String tableName) throws SQLException {
        try(ResultSet pkColumns= connection.getMetaData().getPrimaryKeys(null,null,tableName);) {
          SortedSet<String> pkColumnSet = new TreeSet<>();
          while(pkColumns.next()) {
            String pkColumnName = pkColumns.getString("COLUMN_NAME");
            Integer pkPosition = pkColumns.getInt("KEY_SEQ");
            out.println(""+pkColumnName+" is the "+pkPosition+". column of the primary key of the table "+tableName);
            pkColumnSet.add(pkColumnName);
          }
          return pkColumnSet;
        }
    

答案 1 :(得分:4)

我想知道使用ResultSet检查表中的列是否为主键

在MySql JDBC驱动程序中,如果仔细查看,java.sql.ResultSetMetaData的实际实现类将是com.mysql.jdbc.ResultSetMetaData类。此类提供protected方法来获取有关每个字段的信息

protected Field getField(int columnIndex) throws SQLException {

此方法可以为每个Field索引提供column实例。 使用Field实例,您可以访问Field 的属性。要检查它是否是主键,您可以调用

Field.isPrimaryKey() 

com.mysql.jdbc.ResultSetMetaData类型广告中使用((com.mysql.jdbc.ResultSetMetaData) rsmd).getField(i).isPrimaryKey()的FQN。这是因为您无法导入两个具有相同名称的类文件并在文件中使用它们

请阅读MySql JDBC API中的Field文档以了解有关它的更多信息。希望这有帮助!

答案 2 :(得分:2)

使用@Keerthivasan方法这里是完整的工作代码。唯一的问题是答案不能使用像protected方法那样的方法。 这是工作代码。

ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
int count = resultSetMetaData.getColumnCount();
for (int x = 1; x <= count; x++) {

    Method method = null;
    try {
        method = com.mysql.jdbc.ResultSetMetaData.class.getDeclaredMethod("getField", int.class);
        method.setAccessible(true);
        com.mysql.jdbc.Field field = (com.mysql.jdbc.Field) method.invoke(resultSetMetaData, x);

        if (field.isPrimaryKey()) {
            System.out.println("-----------PK---------------------");
        } else {
            System.out.println("+++++++++++++++NPK++++++++++++++++++");
        }
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    }


}

答案 3 :(得分:1)

    // find primary keys
    try {
        ResultSet rs = conn.getMetaData().getPrimaryKeys(null, conn.getSchema(), table);
        while (rs.next()) {
            System.out.println(rs.getString("COLUMN_NAME") + ":" + rs.getString("KEY_SEQ"));
        }
    } catch (SQLException e) {
        e.printStackTrace();
    }

这将适用于所有RDBMS,不一定适用于MSSQL