跳转到内容

Java JDBC 使用 SQLite/元数据

来自维基教科书,开放世界中的开放书籍

使用元数据

[编辑 | 编辑源代码]

在处理数据库对象时,总会遇到需要了解数据库结构比你编写代码时所了解的更多的情况。数据库表会发生变化,例如,列类型可能从日期类型更改为字符串类型,或者可能添加或删除新的列;你可能需要引用尚未构建的表,或者是在运行时构建的表。在这种情况,JDBC 的一个非常有用的方面就派上用场了:元数据接口 ResultSetMetaData 和 DatabaseMetaData。

在处理结果集时,重要的是要记住数组是从 SQL 的角度构建的,即它们从值为 1 而不是 0 的索引开始。你还应该注意,在处理包含 0 行的表的元数据时,SqLite 和 JDBC 可能存在问题;例如,rsmd.getColumnType() 无法正常工作,而 rsmd.getColumnName() 奇妙的是可以工作的。

让我们考虑以下基本的示例,从中我们可以知道任何任意结果集返回的列的范围

  public int getColumnCount(ResultSet rs) {
    int iOutput = 0;
        try {
            ResultSetMetaData rsMetaData = rs.getMetaData();
            iOutput = rsMetaData.getColumnCount();
        } catch (Exception e) {
            System.out.println(e);
            return iOutput = -1;
        }
    return iOutput;
    }

因此,使用之前 Db.executeQry(java.lang.String) 包装方法,我们可以做一些非常简单的事情,例如

[..]
   String mySqlSelect = "SELECT * FROM some_arbitrary_table" ;
   ResultSet myRs = db.executeQry(mySqlSelect);
   int iResult = getColumnCount(myRs);
   System.out.println(iResult);

现在我们需要知道列类型……

 public int[] getType(ResultSet rs) {
        int iType[] = null;
        try {
            ResultSetMetaData rm = rs.getMetaData();
            int iArray[] = new int[rm.getColumnCount()];
            for (int ctr = 1; ctr <= iArray.length; ctr++) {
                int iVal = rm.getColumnType(ctr);
                iArray[ctr - 1] = iVal;
            }
            return iArray;
        } catch (Exception e) {
            System.out.println(e);
            return iType;
        }
    }

这将返回一个整数数组,表示结果集中的列类型。我们可能需要将这些整数值处理为字符串,因此执行此操作的另一种方法如下

  public String[] getColumnTypeArray(ResultSet rs) {
        String sArr[] = null;
        try {
            ResultSetMetaData rm = rs.getMetaData();
            String sArray[] = new String[rm.getColumnCount()];
            for (int ctr = 1; ctr <= sArray.length; ctr++) {
                String s = rm.getColumnTypeName(ctr);
                sArray[ctr - 1] = s;
            }
            return sArray;
        } catch (Exception e) {
            System.out.println(e);
            return sArr;
        }
    }

整数数组和字符串数组之间的相关性是 java.sql.Types 类的一个方面。两种方式都适用于编程目的。

因此,我们现在知道了结果集的列范围及其数据类型。现在我们需要知道列名,以便我们可以引用它们。ResultSetMetaData 再次提供了答案

 public String[] getColumnNameArray(ResultSet rs) {
        String sArr[] = null;
        try {
            ResultSetMetaData rm = rs.getMetaData();
            String sArray[] = new String[rm.getColumnCount()];
            for (int ctr = 1; ctr <= sArray.length; ctr++) {
                String s = rm.getColumnName(ctr);
                sArray[ctr - 1] = s;
            }
            return sArray;
        } catch (Exception e) {
            System.out.println(e);
            return sArr;
        }
    }


因此,使用之前的 Db.executeQry 包装方法,我们现在可以开始处理未知和/或不可预见数据库结构

  [..]
  String mySqlSelect = "SELECT * FROM some_arbitrary_table" ;  
  ResultSet myRs = db.executeQry(mySqlSelect);  
  int iResult = getColumnCount(myRs);  
  String[] colNames = getColumnNameArray(myRs);
  String[] colTypes = getColumnTypeArray(myRs);
  for (int i=1;i<iResult;i++)
  {
     System.out.println("Column: " + i + " is " + colNames[i] + " and is type: " + colTypes[i]);
  }
华夏公益教科书