1. 程式人生 > >Sql Server的儲存過程與Java程式碼相連線呼叫(二)

Sql Server的儲存過程與Java程式碼相連線呼叫(二)

        我所寫的專案是使用Maven開發,在pom.xml中新增如下必要依賴:
        新增com.microsoft.sqlserver的mssql-jdbc 6.2.1.jre8的依賴

<dependency>  
    <groupId>com.microsoft.sqlserver</groupId>  
    <artifactId>mssql-jdbc</artifactId>  
    <version>6.2.1.jre8</version>  
</dependency> 

        

        在下面的Java程式碼塊中,涉及到如何在Java中建立SQL Server的“表值變數”(臨時表),以及Java程式碼如何去呼叫SQL Server的儲存過程,如何傳遞在Java程式碼中所寫的“表值變數”(臨時表)。其中,程式碼中所呼叫的 proc_test01儲存過程,可參考我寫的部落格:SQL Server資料庫學習之 -- 儲存過程-遊標-表值型別綜合運用

       我所寫的程式碼有些簡化,以“學生 -- 班級 -- 教師”這種經典模式來講解自己所運用的知識點。可能網友直接將我的程式碼貼上-複製,執行會報錯。不過其中的知識點確是無誤的!

        在本篇文章中,最重要的是其運用到SQL Server表值型別變數這塊知識。關於在Java程式碼中引入的Sql Server-Jar包,不能太低,否則無法使用“表值型別變數”這塊知識。 

import java.util.Map;

import com.microsoft.sqlserver.jdbc.SQLServerCallableStatement;
import com.microsoft.sqlserver.jdbc.SQLServerDataTable;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.CallableStatementCallback;
import org.springframework.jdbc.core.CallableStatementCreator;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

@Service
public class ClazzService {
        /**
	 * 批量提交班級資訊
	 */
	public int putClazz(Clazz clazz) throws SQLException {
		Integer count = 0;  
		
		Integer testCount = sqlServerJdbcTemplate.execute(
				new CallableStatementCreator() {
					@Override
					public CallableStatement createCallableStatement(Connection con) throws SQLException {
						SQLServerCallableStatement cs = (SQLServerCallableStatement) con.prepareCall("exec proc_test01 ?, ?");
						// 設定儲存過程中所用的臨時表名
						SQLServerDataTable sourceDataTable = new SQLServerDataTable();
						
						// 為臨時表sourceDataTable新增表頭欄位和欄位型別
						sourceDataTable.addColumnMetadata("TEACHER", java.sql.Types.VARCHAR);
						sourceDataTable.addColumnMetadata("CLANO", java.sql.Types.VARCHAR);
						sourceDataTable.addColumnMetadata("SEX", java.sql.Types.CHAR);
						sourceDataTable.addColumnMetadata("NAME", java.sql.Types.VARCHAR);
						sourceDataTable.addColumnMetadata("AGE", java.sql.Types.INTEGER);
						sourceDataTable.addColumnMetadata("STUNO", java.sql.Types.INTEGER);
						
						
						// 可一次性將多個不同學生插入到同一個班級中
						for (Student student : clazz.getStudent()) {
							// 將資料新增進建立的Table表中
							sourceDataTable.addRow(clazz.getTeacher(), clazz.getClaNo(), 
													student.getSex(), student.getName(),
													student.getAge(), student.getStuNo());
						}
						
						// 字串"clazz_Table"為呼叫資料庫儲存過程“proc_test01”中,其內部編寫的臨時表名稱
						cs.setStructured(1, "clazz_Table", sourceDataTable);
						cs.registerOutParameter(2, java.sql.Types.INTEGER);   // 可返回值的引數
						
						return cs;
					}
				}, 
				new CallableStatementCallback<Integer>() {
					@Override
					public Integer doInCallableStatement(CallableStatement cs) throws SQLException, DataAccessException {
						cs.execute();
						return cs.getInt(2);   // 將第“2”個引數的值返回。第“2”個引數,其型別是“返回值型別引數”
					}
				}
			);
		
		count = testCount;   // 將testCount變數賦值給count變數
		return count;
		
	}  // public int putClazz(Clazz clazz)
    
}

Student.java類(學生類),其程式碼如下

package com.entity;

public class Student {
	
	private char sex;  // 性別
	
	private String name;  // 姓名
	
	private int age;      // 年齡
	
	private int stuNo;    // 學號  
	
	
	public char getSex() {
		return sex;
	}

	public void setSex(char sex) {
		this.sex = sex;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public int getStuNo() {
		return stuNo;
	}

	public void setStuNo(int stuNo) {
		this.stuNo = stuNo;
	}
	
	
}

Clazz.java類(班級類)
package com.entity;

import java.util.List;

public class Clazz {
	
	private String teacher;   // 班主任
	
	private String claNo;     // 班級編號
	
	private List<Student> stuList;  //學生

	public String getTeacher() {
		return teacher;
	}

	public void setTeacher(String teacher) {
		this.teacher = teacher;
	}

	public String getClaNo() {
		return claNo;
	}

	public void setClaNo(String claNo) {
		this.claNo = claNo;
	}

	public List<Student> getStuList() {
		return stuList;
	}

	public void setStuList(List<Student> stuList) {
		this.stuList = stuList;
	}
	
	
	
}

--------------------------------------------------------------------------

--------------------------------------------------------------------------

例如,寫一介面,呼叫putClazz()函式,則可傳遞一組JSON資料,其資料格式如下所示。通過呼叫putClazz()函式,可以做到在一次提交資料過程中:一個班級可以插入多個學生資訊。

JSON格式程式碼:

{
    "teacher": "吳老師",
    "clano": "打雜1班",
    "stuList": [
        {
            "sex": "男",
            "name": "吃瓜群眾",
            "age": 18,
            "stuNo": 101001
        },
        {
            "sex": "女",
            "name": "如花",
            "age": 16,
            "stuNo": 101002
        },
        {
            "sex": "女",
            "name": "齙牙珍",
            "age": 20,
            "stuNo": 101001
        }
    ]
}