繁体   English   中英

从 ResultSet Java 中获取主键列

[英]Get Primary Key Column from ResultSet Java

我正在尝试从 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 对象已经具有我只需要获取的主键信息。

关于您的问题的一些想法以及解决方案(希望有帮助):

在我的一生中,我没有想到使用结果集元数据中具有主键信息的结果集。

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

例如,我们可能会发出这样的查询

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

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

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

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

  1. (不是我喜欢的方式)
    转换到特定的实现ResultSetMetaData -class 并访问主键信息(如果可用)。 但请注意,并非每个
    ResultSetMetaData实现提供了此信息。

  2. (更多的架构方法,我也没有提出,但需要
    如果我们处理不完整的 JDBC 驱动程序)
    利用您使用的不同数据库的系统表,但当然会将其隐藏在抽象中,例如桥接模式。 根据您的资助,您通常没什么大不了的(包括测试基础架构部分最多 4 人天的工作,以及您想要访问的每个数据库系统大约 1 人天的工作)然后您从那里包括关于外键关系。

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

这是一个代码片段(在 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;
    }

我有一个想法来检查表中的 Column 是否使用ResultSet

在MySql JDBC驱动中,仔细看, java.sql.ResultSetMetaData真正的实现类应该是com.mysql.jdbc.ResultSetMetaData类。 此类提供了一个protected方法来获取有关每个字段的信息

protected Field getField(int columnIndex) throws SQLException {

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

Field.isPrimaryKey() 

在您的类型com.mysql.jdbc.ResultSetMetaData中使用com.mysql.jdbc.ResultSetMetaData FQN,如((com.mysql.jdbc.ResultSetMetaData) rsmd).getField(i).isPrimaryKey() 这是因为您不能导入两个同名的类文件并在整个文件中使用它们

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

使用@Keerthivasan Approach 这里是完整的工作代码。 唯一的问题是答案不能使用这样的方法,因为它是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();
    }


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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM