首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 實現 .NET DataTable 功能系列(三):參數化查詢與調用實戰

     編輯:Java 相關知識

本系列第三部分,展示如何在自製 DataTable 元件中實現參數化 SQL 查詢(防 SQL 注入),並演示實際業務調用代碼。

核心方法:addSqlParameter — 參數綁定邏輯


/**
 * 為 PreparedStatement 綁定參數陣列
 * @param ps 預編譯語句
 * @param params SqlParameter 陣列,含型別與值
 */
private void addSqlParameter(PreparedStatement ps, SqlParameter[] params) throws SQLException {
    for (int i = 0; i < params.length; i++) {
        SqlParameter p = params[i];
        String type = p.getType();
        
        if ("int".equals(type)) {
            ps.setInt(i + 1, p.getIntValue());
        } else if ("String".equals(type)) {
            ps.setString(i + 1, p.getValue());
        } else if ("boolean".equals(type)) {
            ps.setBoolean(i + 1, p.getBoolValue());
        } else if ("Date".equals(type)) {
            ps.setDate(i + 1, p.getDateValue());
        } else if ("Blob".equals(type)) {
            ps.setBlob(i + 1, p.getBlobValue());
        }
        // 可擴充更多型別:BigDecimal, Timestamp, Clob 等
    }
}

設計要點:

  • 使用 PreparedStatement 預編譯,徹底防範 SQL 注入。
  • 參數型別以字串標識,運行期分發至對應 setXxx 方法。
  • 索引從 1 開始(JDBC 規範),迴圈用 i + 1。

業務調用範例:getByParentId


public DataTable getByParentId(int parentId) {
    String sql = "SELECT * FROM kpxz WHERE fbh = ? ORDER BY kpxzsx ASC";
    
    SqlParameter[] params = new SqlParameter[1];
    params[0] = new SqlParameter("int", parentId);
    
    return db.getDataTable(sql, params);
}

SqlParameter 類別回顧(系列二定義)


public class SqlParameter {
    private String type;
    private String value;
    private int intValue;
    private boolean boolValue;
    private Date dateValue;
    private Blob blobValue;
    
    // 多型別建構子
    public SqlParameter(String type, String value) { this.type = type; this.value = value; }
    public SqlParameter(String type, int intValue) { this.type = type; this.intValue = intValue; }
    public SqlParameter(String type, boolean boolValue) { this.type = type; this.boolValue = boolValue; }
    public SqlParameter(String type, Date dateValue) { this.type = type; this.dateValue = dateValue; }
    public SqlParameter(String type, Blob blobValue) { this.type = type; this.blobValue = blobValue; }
    
    // Getter/Setter 略
}

完整查詢流程圖解

getByParentId(123)
    ↓
sql = "SELECT ... WHERE fbh = ?"
params = [SqlParameter("int", 123)]
    ↓
db.getDataTable(sql, params)
    ↓
Connection conn = DB.createConn()
PreparedStatement ps = conn.prepareStatement(sql)
    ↓
addSqlParameter(ps, params)  ← 關鍵:ps.setInt(1, 123)
    ↓
ResultSet rs = ps.executeQuery()
    ↓
ResultSetMetaData → 列名/型別
    ↓
while (rs.next()) {
    List rowColumns = new ArrayList<>();
    for (int i = 1; i <= columnCount; i++) {
        String colName = rsmd.getColumnName(i);
        Object val = rs.getObject(colName);
        rowColumns.add(new DataColumn(colName, val));
    }
    rows.add(new DataRow(rowColumns));
}
    ↓
return new DataTable(rows)

擴充建議

  • 支援 BigDecimal、Timestamp、Clob、Array 等更多 JDBC 型別。
  • 加入參數名稱支援(ps.setObject("paramName", val),需 JDBC 4.0+ 驅動)。
  • 整合連線池(HikariCP/Druid)替換簡易 DB.createConn()。
  • 加入查詢超時設定:ps.setQueryTimeout(seconds)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved