从ResultSet Java获取主键列

SID*_*SID 4 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.
Run Code Online (Sandbox Code Playgroud)

这是有趣的部分.

3. ResultSetMetadata rsmd = rs.getMetadata();
Run Code Online (Sandbox Code Playgroud)

现在,如果我观察这个变量" rsmd ",它会显示相关列名的主键标志,但我无法访问它或将其转换为任何变量.

我需要帮助.

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

小智 6

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

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

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

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

select X.a, X.b, Y.n, Y.m, 'bla'||X.c||'blub'||Y.l from X, Y;
Run Code Online (Sandbox Code Playgroud)

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

您已经知道标准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;
    }
Run Code Online (Sandbox Code Playgroud)


Kee*_*san 5

我有一个想法来检查表中的列是否是主键或不使用ResultSet.

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

protected Field getField(int columnIndex) throws SQLException {
Run Code Online (Sandbox Code Playgroud)

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

Field.isPrimaryKey() 
Run Code Online (Sandbox Code Playgroud)

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

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

  • @Keerthivasan 不,这行不通。当方法受到保护时,您的类应该是该类的子类或在同一个包中。但你的方法值得赞赏。你可以使用反射来完成这项工作。`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); System.out.println(field.isPrimaryKey());` (4认同)