在 Java Swing 桌面應用開發中,JTable 是展示表格資料的核心組件。本文深度解析將資料庫查詢結果綁定至 JTable 的兩種主流方案:二維陣列模式與 TableModel 模式,並提供完整可執行代碼範例。
JTable 提供兩個關鍵建構子支援資料綁定:
JTable(Object[][] rowData, Object[] columnNames):直接接受二維陣列資料與欄位名稱陣列,適合靜態資料或一次性載入場景。JTable(TableModel dm):接受實作 TableModel 介面的資料模型,支援動態資料更新、排序、過濾等進階功能,屬企業級開發首選。基於前文 PreparedStatement 預編譯技術,封裝通用查詢方法返回 ResultSet:
/** 查詢並返回可滾動唯讀 ResultSet */
public ResultSet getResultSet(String sql, Object[] params) {
getConnection();
try {
pStatement = connection.prepareStatement(
sql,
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY
);
if (params != null && params.length > 0) {
for (int i = 0; i < params.length; i++) {
pStatement.setObject(i + 1, params[i]);
}
}
rSet = pStatement.executeQuery();
} catch (SQLException e) {
e.printStackTrace();
}
return rSet;
}
/** 將 ResultSet 轉換為 Object[][] 二維陣列 */
public Object[][] resultSetToObjectArray(ResultSet rs) {
Object[][] data = null;
try {
rs.last(); // 移至最後一行獲取總行數
int rows = rs.getRow();
data = new Object[rows][];
ResultSetMetaData meta = rs.getMetaData();
int columnCount = meta.getColumnCount();
rs.first(); // 移至第一行開始讀取
int rowIndex = 0;
while (rs.next()) {
Object[] row = new Object[columnCount];
for (int col = 0; col < columnCount; col++) {
row[col] = rs.getObject(col + 1).toString();
}
data[rowIndex++] = row;
}
} catch (Exception e) {
e.printStackTrace();
}
return data;
}
DefaultTableModel 並設定給 JTable// Swing 視圖類中
UserDAO userDAO = new UserDAO();
// 1. 獲取二維陣列資料
Object[][] tableData = userDAO.resultSetToObjectArray(
userDAO.getResultSet("select id, username, password from t_userr", null)
);
// 2. 定義欄位名稱
String[] columnNames = {"id", "username", "password"};
// 3. 綁定模型
jTable1.setModel(new DefaultTableModel(tableData, columnNames));

透過 MyEclipse 視覺化設計器配置 JTable 的 model 屬性為「代碼來源」,指定靜態方法路徑:
model 屬性包名.類名.靜態方法名

public static TableModel getMemberTableModel() {
// 模擬資料容器(實際應從 DAO 獲取)
String[][] playerInfo = new String[80][8];
BaseDAO bDao = new BaseDAO();
String sql = "select id, realName, username, sex, phone, email, vocation, city from jdbctest";
ArrayList<HashMap<Object, Object>> list = bDao.Query(sql, new String[]{});
int row = 0, col = 0;
for (HashMap<Object, Object> map : list) {
for (Object key : map.keySet()) {
playerInfo[row][col++] = map.get(key).toString();
}
row++;
col = 0;
}
String[] columnNames = {"id", "username", "sex", "phone", "vocation", "email", "realName", "city"};
return new DefaultTableModel(playerInfo, columnNames);
}

| 維度 | 二維陣列模式 | TableModel 模式 |
|---|---|---|
| 實現複雜度 | 低,適合快速原型 | 中,需實作介面或繼承 DefaultTableModel |
| 資料動態更新 | 不支援,需重新 setModel | 支援 fireTableDataChanged() 通知視圖更新 |
| 記憶體效率 | 一次性載入所有資料 | 可實作分頁載入、虛擬化模型 |
| 功能擴展性 | 排序、過濾需自行實現 | 原生支援 RowSorter、TableRowSorter |
| 適用場景 | 資料量小、靜態展示 | 企業級應用、大數據集、需互動操作 |
最佳實踐:新專案優先採用TableModel模式,配合AbstractTableModel實作自定義模型,實現資料與視圖解耦,支援未來功能擴展。