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

Spring 調用存儲過程:StoredProcedure 封裝最佳實踐

     編輯:Java 相關知識

核心類體系

org.springframework.jdbc.object.StoredProcedure 繼承 SqlCall(提供 CallableStatementCreator 底層支援),是抽象類,需子類化封裝具體存儲過程調用。

實戰示例:MySQL 存儲過程

CREATE PROCEDURE CountTable(IN tableName varchar(1000), OUT sqlStr varchar(1000), INOUT v INT)
BEGIN
    SET @flag = v;
    SET @sql = CONCAT('select count(*) into @res from ', tableName, ' where ACTIVE_FLAG=?');
    PREPARE stmt FROM @sql;
    EXECUTE stmt USING @flag;
    DEALLOCATE PREPARE stmt;
    SET v = @res;
    SET sqlStr = @sql;
END

操作對象封裝

public class CountTableStoredProcedure extends StoredProcedure {
    private static final String PROC_NAME = "CountTable";
    public static final String IN_PARAM = "tableName";
    public static final String OUT_PARAM = "sqlStr";
    public static final String INOUT_PARAM = "v";

    public CountTableStoredProcedure(DataSource ds) {
        super(ds, PROC_NAME);
        // setFunction(true); // 若為 FUNCTION 則啟用
        declareParameter(new SqlParameter(IN_PARAM, Types.VARCHAR));
        declareParameter(new SqlOutParameter(OUT_PARAM, Types.VARCHAR));
        declareParameter(new SqlInOutParameter(INOUT_PARAM, Types.INTEGER));
        compile(); // 必須調用,構建底層 CallableStatement
    }

    public CountTableResult doCountTable(String tableName, Integer v) {
        Map inMap = new HashMap<>();
        inMap.put(IN_PARAM, tableName);
        inMap.put(INOUT_PARAM, v);

        Map outMap = execute(inMap);

        CountTableResult result = new CountTableResult();
        result.setSql((String) outMap.get(OUT_PARAM));
        result.setCount((Integer) outMap.get(INOUT_PARAM));
        return result; // 強類型結果對象,而非原始 Map
    }
}

關鍵細節解析

  • SQL 名稱即存儲過程名:compile() 會自動生成標準調用語法 {call CountTable(?,?,?)}
  • 參數聲明順序必須與存儲過程定義一致:IN/OUT/INOUT 對應 SqlParameter/SqlOutParameter/SqlInOutParameter
  • 參數名稱作為 Map Key:輸入 Map、輸出 Map 的 Key 必須與 declareParameter 時指定的名稱完全一致,建議定義為常量
  • Function vs Procedure:調用 FUNCTION 時需 setFunction(true)

調用端極簡代碼

CountTableStoredProcedure proc = new CountTableStoredProcedure(dataSource);
CountTableResult result = proc.doCountTable("my_table", 1);
// 直接使用 result.getSql(), result.getCount()

進階:ParameterMapper 回調

當構造輸入參數需要 Connection 時(如 Oracle ARRAY 類型),使用 execute(ParameterMapper):

public Map callOracleArrayProc() {
    ParameterMapper mapper = new ParameterMapper() {
        public Map createMap(Connection con) throws SQLException {
            Map in = new HashMap();
            Integer[] arr = {1, 2};
            ArrayDescriptor desc = new ArrayDescriptor("NUMBERS", con);
            ARRAY oracleArray = new ARRAY(desc, con, arr);
            in.put("arrayParam", oracleArray);
            return in;
        }
    };
    return execute(mapper);
}

普通場景下 execute(Map) 更簡潔,ParameterMapper 為特殊數據類型提供底層連接訪問能力。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved