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

Spring Framework 整合 DB2 預存程序實戰:參數傳遞、結果集處理與多結果集支援

     編輯:DB2 教學

前言與適用對象

Spring Framework 廣泛用於輕量級 J2EE 開發邏輯層,與 Struts、WebWork、Hibernate 等開源專案整合良好,重構既有系統時尤顯威力。預存程序可封裝業務邏輯、控制權限、處理 CRUD。重構時業務邏輯不變,僅需調整呼叫方式。Spring 提供完整預存程序封裝與資料源管理,讓開發者輕鬆建構輕量級 J2EE 應用。

本文提供 Spring + Struts 呼叫 DB2 預存程序完整範例:輸入/輸出參數、單一/多結果集處理、DisplayTag 顯示結果。適用對象:具 DB2 與 Web 開發經驗的開發/設計人員。

核心優勢:Spring DAO 抽象層

  • Spring DAO 為 JDBC 提供抽象層,提升 JDBC 使用效率
  • 統一異常處理機制,切換資料存取技術無需擔心異常處理
  • org.springframework.jdbc.object.StoredProcedure 抽象類支援輸入/輸出參數與多結果集
  • 避免傳統 JDBC 繁瑣代碼(建立連線、Statement、關閉資源、異常處理)與潛在 Bug

完整實作範例

1. 建立 DB2 環境與預存程序

編目遠端 DB2 伺服器(主機 zxl01.cn.ibm.com,埠 50001):

db2 CATALOG TCPIP NODE node01 REMOTE zxl01.cn.ibm.com SERVER 50001
db2 CATALOG DB testDB AT NODE node01

建立客戶資料表:

DROP TABLE DSW.CUSTOMER@
CREATE TABLE DSW.CUSTOMER(
  CUST_NUM VARCHAR(10) NOT NULL,
  CUST_NAME VARCHAR(35) NOT NULL,
  ADDRESS VARCHAR(35) NOT NULL,
  CITY VARCHAR(35) NOT NULL,
  COUNTRY VARCHAR(3) NOT NULL,
  ADD_DATE TIMESTAMP NOT NULL
)@
ALTER TABLE DSW.CUSTOMER ADD CONSTRAINT CUSTOMER_PK PRIMARY KEY (CUST_NUM)@

建立預存程序 DSW.S_CUSTOMER(輸出狀態碼、輸入客戶編號、返回 2 個結果集):

DROP PROCEDURE DSW.S_CUSTOMER@
CREATE PROCEDURE DSW.S_CUSTOMER (
  OUT poStatus INTEGER,
  IN piCust_num VARCHAR(10)
)
LANGUAGE SQL
SPECIFIC DSW.S_CUSTOMER
RESULT SETS 2
P1: BEGIN NOT ATOMIC
  DECLARE sqlReset CONDITION FOR SQLSTATE '80100';
  DECLARE SQLCODE INTEGER DEFAULT 0;
  DECLARE SQLSTATE CHAR(5) DEFAULT '00000';
  DECLARE hSqlcode INTEGER DEFAULT 0;
  DECLARE hSqlstate CHAR(5) DEFAULT '00000';
  DECLARE v_Cnt INT;

  DECLARE cursor1 CURSOR WITH RETURN TO CLIENT FOR (
    SELECT CUST_NUM, CUST_NAME FROM DSW.CUSTOMER
  );
  DECLARE cursor2 CURSOR WITH RETURN TO CLIENT FOR (
    SELECT * FROM DSW.CUSTOMER WHERE CUST_NUM = piCust_num
  );

  OPEN cursor1;
  OPEN cursor2;
  SET poStatus = 2;
  RETURN poStatus;
END P1@

插入測試資料:

INSERT INTO DSW.CUSTOMER (CUST_NUM,CUST_NAME,ADDRESS,CITY,COUNTRY) VALUES('1','Steven','shang di','BeiJing','CHN')@
INSERT INTO DSW.CUSTOMER (CUST_NUM,CUST_NAME,ADDRESS,CITY,COUNTRY) VALUES('2','David','shang di','BeiJing','CHN')@
INSERT INTO DSW.CUSTOMER (CUST_NUM,CUST_NAME,ADDRESS,CITY,COUNTRY) VALUES('3','Tony','shang di','BeiJing','CHN')@
INSERT INTO DSW.CUSTOMER (CUST_NUM,CUST_NAME,ADDRESS,CITY,COUNTRY) VALUES('4','Maggie','shang di','BeiJing','CHN')@

2. 建立 Spring + Struts Web 應用

web.xml 整合 Spring ContextLoaderListener**:

<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>/WEB-INF/applicationContext-service.xml</param-value>
</context-param>
<listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
  <servlet-name>action</servlet-name>
  <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
  <servlet-name>action</servlet-name>
  <url-pattern>*.do</url-pattern>
</servlet-mapping>

3. Spring 配置資料源與 DAO Bean

applicationContext-service.xml**:

<beans>
  <bean id="dataSourceJDBC" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName"><value>COM.ibm.db2.jdbc.app.DB2Driver</value></property>
    <property name="url"><value>jdbc:db2:testDB</value></property>
    <property name="username"><value>dsw</value></property>
    <property name="password"><value>pass4spring</value></property>
  </bean>

  <bean id="SearchImpl" class="com.springsproc.dao.jdbc.SearchDAOImpl">
    <property name="dataSource"><ref local="dataSourceJDBC" /></property>
    <property name="sprocName"><value>DSW.S_CUSTOMER</value></property>
  </bean>
</beans>

彈性優勢:資料庫連線資訊寫在配置檔,部署時輕鬆切換 DataSource 實作(如應用伺服器配置的 JNDI DataSource),提升團隊開發效率與系統可維護性。

4. Action 中取得 Bean 執行預存程序

SearchAction.java**(控制反轉 IoC 核心體現):

private static ApplicationContext ctx = null;
public Object getBean(String name) {
  if (ctx == null) {
    ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(servlet.getServletContext());
  }
  return ctx.getBean(name);
}

// 在 execute 方法中:
SearchDAO mgr = (SearchDAO) getBean("SearchImpl");  // (1) 實例化 Bean (2) 取得介面實現
Map map = mgr.execute(custNum);                      // (3) 呼叫具體方法執行預存程序

5. DAO 介面定義

package com.springsproc.dao;
import java.util.List;
public interface SearchDAO {
  public Map execute(String custNum);
}

6. DAO 實作:封裝預存程序呼叫細節

SearchDAOImpl.java**:

public Map execute(String custNum) {
  SearchCustomersProcedure sp = new SearchCustomersProcedure(dataSource);
  Map map = new HashMap(1);
  map.put("piCust_num", custNum);
  Map results = sp.execute(map);  // 執行預存程序
  return results;
}

private class SearchCustomersProcedure extends StoredProcedure {
  SearchCustomersProcedure(DataSource dataSource) {
    super(dataSource, sprocName);  // 設定資料源與預存程序名

    // 宣告第一個結果集
    declareParameter(new SqlReturnResultSet("resultSet", new DemoRowMapper()));

    // 宣告第二個結果集
    declareParameter(new SqlReturnResultSet("resultSet2", new DemoRowMapper2()));

    // 宣告輸出參數
    declareParameter(new SqlOutParameter("poGenStatus", Types.INTEGER));

    // 宣告輸入參數
    declareParameter(new SqlParameter("piCust_num", Types.VARCHAR));
  }
}

// RowMapper 實作:將 ResultSet 映射為領域物件
private class DemoRowMapper implements RowMapper {
  public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
    Customer customer = new Customer();
    customer.setCustNum(rs.getString(1));
    customer.setCustName(rs.getString(2));
    return customer;
  }
}

private class DemoRowMapper2 implements RowMapper {
  public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
    Customer customer = new Customer();
    customer.setCustName(rs.getString(1));
    customer.setCustNum(rs.getString(2));
    customer.setCustAddress(rs.getString(3));
    customer.setCustCity(rs.getString(4));
    customer.setCustCountry(rs.getString(5));
    return customer;
  }
}

7. Spring 關鍵類別速查

類別/介面用途
StoredProcedure抽象類,declareParameter() 宣告參數,execute() 執行呼叫
SqlParameter代表預存程序參數
ResultSetSupportingSqlParameterSqlOutParameter、SqlReturnResultSet 共同基類
SqlOutParameter代表輸出參數
SqlReturnResultSet代表輸出結果集
RowMapper介面,mapRow() 將 ResultSet 映射為物件

8. Struts Action 處理結果與 JSP 顯示

SearchAction.java 續**:

List list = (List) map.get("resultSet");
List list2 = (List) map.get("resultSet2");
String poGenStatus = map.get("poGenStatus").toString();
log.info("poGenStatus is:" + poGenStatus);

request.setAttribute("customerList", list);   // 所有客戶清單
request.setAttribute("MyCustomers", list2);   // 查詢客戶明細
return mapping.findForward("list");

SearchByCustNumber.jsp 使用 DisplayTag**:

<!-- 可排序、指定欄位顯示 -->
<display:table name="customerList" cellspacing="2" cellpadding="2" requestURI="" defaultsort="1" id="customers">
  <display:column property="custNum" sort="true" headerClass="sortable" title="Customer number" headerStyleClass="header"/>
  <display:column property="custName" sort="true" headerClass="sortable" title="Customer name" headerStyleClass="header"/>
</display:table>

<!-- 直接顯示所有欄位 -->
<display:table name="myCustomer" cellspacing="2" cellpadding="2" requestURI="" defaultsort="1" id="myCustomer">
</display:table>

執行結果截圖:
執行結果畫面

Spring Framework 整合優勢總結

  • 封裝資料庫操作細節,開發者專注業務邏輯
  • 資料庫連線資訊外部化配置,部署靈活、團隊協作高效、維護性強
  • IoC 容器管理 Bean 生命週期,降低耦合度
  • 統一異常處理,切換資料存取技術無痛
  • 完整支援預存程序輸入/輸出參數、單一/多結果集

結語

本文以完整實例展示 Spring Framework 呼叫 DB2 預存程序的方法,涵蓋參數傳遞、多結果集處理、DisplayTag 前端顯示。參考此範例,您可結合不同類型預存程序操作 DB2 資料,並快速建構基於 Struts + Spring 的 Web 應用系統。

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