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

J2EE 實戰:基於表單命名規約的 SQL 陳述式自動建構引擎

     編輯:關於SqlServer

在 Web 開發中,INSERT、DELETE、UPDATE 三大 SQL 操作佔據絕大多數資料存取邏輯。手工拼接 SQL 不僅繁瑣易錯,更難以應對欄位變更。本文提出一套**基於表單元素命名規約**的自動 SQL 建構方案,實現「零手寫 SQL」的通用資料存取層。

核心設計理念:約定優於配置

約定表單元素 name 屬性與資料庫欄位一一對應,並透過前綴區分資料型別與語義角色:

前綴語義處理邏輯範例
c_ (common)公共控制參數不進入欄位清單,控制 SQL 結構c_table (表名)、c_genre (INSERT/UPDATE/DELETE)、c_where (WHERE 條件)
s_ (string)字串型欄位自動加單引號,雙單引號轉義s_username → 'john''doe'
i_ (integer)非字串型欄位不加引號,支援數值、函式 (NOW())、NULLi_age → 25、i_created → NOW()

JavaBean 核心實現 (PageUtil.java)

package com.river.page;

import java.util.*;
import javax.servlet.http.HttpServletRequest;

public class PageUtil {
    private HttpServletRequest request;

    public void init(HttpServletRequest req) { this.request = req; }
    public void clear() { this.request = null; }

    private String get(String name) {
        return (request != null && request.getParameter(name) != null) 
               ? request.getParameter(name) : "";
    }

    public String getSQL(HttpServletRequest req) {
        init(req);
        return getSQL();
    }

    public String getSQL() {
        String c_table = get("c_table");
        String c_genre = get("c_genre");
        String c_where = get("c_where");
        if (c_genre == null || c_genre.isEmpty()) return "action is null/empty";
        if (c_table == null || c_table.isEmpty()) return "unknown table/empty";

        Enumeration names = request.getParameterNames();
        StringBuilder cols = new StringBuilder(), vals = new StringBuilder(), sets = new StringBuilder();

        while (names.hasMoreElements()) {
            String pName = names.nextElement().trim();
            if (pName.length() < 2) continue;
            String prefix = pName.substring(0, 2).toLowerCase();
            String colName = pName.substring(2);
            String val = get(pName);

            if ("i_".equals(prefix)) { // 非字串型
                if (c_genre.equalsIgnoreCase("INSERT")) {
                    appendComma(cols, colName);
                    appendComma(vals, val.isEmpty() ? "NULL" : val);
                } else if (c_genre.equalsIgnoreCase("UPDATE")) {
                    appendComma(sets, colName + "=" + (val.isEmpty() ? "NULL" : val));
                }
            } else if ("s_".equals(prefix)) { // 字串型
                String sqlVal = val.isEmpty() ? "NULL" : "'" + val.replace("'", "''") + "'";
                if (c_genre.equalsIgnoreCase("INSERT")) {
                    appendComma(cols, colName);
                    appendComma(vals, sqlVal);
                } else if (c_genre.equalsIgnoreCase("UPDATE")) {
                    appendComma(sets, colName + "=" + sqlVal);
                }
            }
        }

        String sql;
        if (c_genre.equalsIgnoreCase("INSERT")) {
            sql = "INSERT INTO " + c_table + " (" + cols + ") VALUES (" + vals + ")";
        } else if (c_genre.equalsIgnoreCase("UPDATE")) {
            sql = "UPDATE " + c_table + " SET " + sets;
            if (!c_where.isEmpty()) sql += " WHERE " + c_where;
        } else if (c_genre.equalsIgnoreCase("DELETE")) {
            sql = "DELETE FROM " + c_table;
            if (!c_where.isEmpty()) sql += " WHERE " + c_where;
        } else {
            return "unknown action type: " + c_genre;
        }
        return sql;
    }

    private void appendComma(StringBuilder sb, String val) {
        if (sb.length() > 0) sb.append(",");
        sb.append(val);
    }
}

前端表單範例

<form action="save.action" method="post">
    <!-- 控制參數 -->
    <input type="hidden" name="c_table" value="users" />
    <input type="hidden" name="c_genre" value="INSERT" />
    <input type="hidden" name="c_where" value="id=100" /> <!-- UPDATE/DELETE 使用 -->

    <!-- 字串欄位 -->
    <input name="s_username" value="john'doe" />  <!-- 自動轉義為 'john''doe' -->
    <input name="s_email" value="john@example.com" />

    <!-- 非字串欄位 -->
    <input name="i_age" value="30" />
    <input name="i_status" value="1" />
    <input name="i_created" value="NOW()" /> <!-- 資料庫函式直通 -->
    <button type="submit">儲存</button>
</form>

生成 SQL 範例

-- INSERT
INSERT INTO users (username,email,age,status,created) 
VALUES ('john''doe','john@example.com',30,1,NOW());

-- UPDATE (c_genre=UPDATE, c_where=id=100)
UPDATE users SET username='john''doe',email='john@example.com',age=30,status=1,created=NOW() WHERE id=100;

-- DELETE (c_genre=DELETE, c_where=id=100)
DELETE FROM users WHERE id=100;

優缺點權衡

優點

  • 開發效率飛躍: 消除重複 CRUD 代碼,新增欄位只需加表單元素。
  • 型別安全與防注入: 統一處理單引號轉義,i_ 前綴避免字串注入風險。
  • 分層解耦: 表單結構變更不影響 Service/Dao 層邏輯。
  • 通用性強: 單一 Action 可處理所有基礎增刪改操作。

缺點與適用場景

  • 效能開銷: 反射遍歷參數、字串拼接,極大量表單 (百欄位以上) 有感知延遲。
  • 複雜查詢不適用: 多表 JOIN、子查詢、動態 WHERE 條件組合仍需手寫。
  • 適用建議: 中小型專案、後台管理系統、表單導向 CRUD 密集場景。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved