当执行SQL査询后可以通过移动记录指针来遍历ResultSet的每条记录,但程序可能不清楚该ResultSet里包含哪些数据列,以及每个数据列的数据类型,那么可以通过ResultSetMetaData来获取关于ResultSet的描述信息。MetaData的意思是元数据,即描述其他数据的数据,因此ResultSetMetaData封装了描述ResultSet对象的数据;后面还要介绍的Database Meta Data则封装了描述Database的数据ResultSet里包含一个getMetaData()方法,该方法返回该ResultSet对应的ResultSetMetaData对象旦获得了ResultSetMetaData对象,就可通过ResultSetMetaData提供的大量方法来返回ResultSet的描述信息。常用的方法有如下三个。
int getColumnCount():返回该ResultSet的列数量。
String getColumnName(int column):返回指定索引的列名。
int getType(int column):返回指定索引的列类型。
下面是一个简单的查询执行器,当用户在文本框内输入合法的查询语句并执行成功后,下面的表格将会显示查询结果。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 import java.awt.*;import java.awt.event.*;import javax.swing.*;import javax.swing.table.*;import java.util.*;import java.io.*;import java.sql.*;public class QueryExecutor { JFrame jf = new JFrame("查询执行器" ); private JScrollPane scrollPane; private JButton execBn = new JButton("查询" ); private JTextField sqlField = new JTextField(45 ); private static Connection conn; private static Statement stmt; static { try { Properties props = new Properties(); props.load(new FileInputStream("mysql.ini" )); String drivers = props.getProperty("driver" ); String url = props.getProperty("url" ); String username = props.getProperty("user" ); String password = props.getProperty("pass" ); Class.forName(drivers); conn = DriverManager.getConnection(url, username, password); stmt = conn.createStatement(); } catch (Exception e) { e.printStackTrace(); } } public void init () { JPanel top = new JPanel(); top.add(new JLabel("输入查询语句:" )); top.add(sqlField); top.add(execBn); execBn.addActionListener(new ExceListener()); sqlField.addActionListener(new ExceListener()); jf.add(top, BorderLayout.NORTH); jf.setSize(680 , 480 ); jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jf.setVisible(true ); } class ExceListener implements ActionListener { public void actionPerformed (ActionEvent evt) { if (scrollPane != null ) { jf.remove(scrollPane); } try ( ResultSet rs = stmt.executeQuery(sqlField.getText())) { ResultSetMetaData resultSetMetaData = rs.getMetaData(); Vector<String> columnNames = new Vector<>(); Vector<Vector<String>> data = new Vector<>(); for (int i = 0 ; i < resultSetMetaData.getColumnCount(); i++) { columnNames.add(resultSetMetaData.getColumnName(i + 1 )); } while (rs.next()) { Vector<String> v = new Vector<>(); for (int i = 0 , length = resultSetMetaData .getColumnCount(); i < length; i++) { v.add(rs.getString(i + 1 )); } data.add(v); } JTable table = new JTable(data, columnNames); scrollPane = new JScrollPane(table); jf.add(scrollPane); jf.validate(); } catch (Exception e) { e.printStackTrace(); } } } public static void main (String[] args) { new QueryExecutor().init(); } }
在上面的程序中使用ResultSetMetaData查询ResultSet包含多少列,并把所有数据列的列名添加到一个Vector里,然后把ResultSet里的所有数据添加到另一个Vector里,并使用这两个Vector来创建新的TableModel,再利用该TableMode生成一个新的JTable,最后将该JTable显示出来。 运行上面程序,在文本框中输入select * from student_table然后点击查询,会看到如图13.21所示的窗口。
注意: 虽然ResultSetMetaData可以准确地分析出ResultSet里包含多少列,以及每列的列名、数据类型等,但使用ResultSetMetaData需要一定的系统开销,因此如果在编程过程中已经知道ResultSet里包含多少列,以及每列的列名、类型等信息,就没有必要使用ResultSetMetaData来分析该ResultSet对象了。
原文链接: 13.5.3 使用ResultsetMetaData分析结果集