Sql Server的存儲(chǔ)過(guò)程與Java代碼相連接調(diào)用(二)
? ? ? ? ? ? ? ?
? ? ? ? 我所寫的項(xiàng)目是使用Maven開發(fā),在pom.xml中添加如下必要依賴:
? ? ? ? 添加com.microsoft.sqlserver的mssql-jdbc 6.2.1.jre8的依賴
com.microsoft.sqlserver
mssql-jdbc
6.2.1.jre8
? ? ? ??
? ? ? ? 在下面的Java代碼塊中,涉及到如何在Java中創(chuàng)建SQL Server的“表值變量”(臨時(shí)表),以及Java代碼如何去調(diào)用SQL Server的存儲(chǔ)過(guò)程,如何傳遞在Java代碼中所寫的“表值變量”(臨時(shí)表)。其中,代碼中所調(diào)用的 proc_test01存儲(chǔ)過(guò)程,可參考我寫的博客:SQL Server數(shù)據(jù)庫(kù)學(xué)習(xí)之 -- 存儲(chǔ)過(guò)程-游標(biāo)-表值類型綜合運(yùn)用
? ? ? ?
? ? ? ?我所寫的代碼有些簡(jiǎn)化,以“學(xué)生 -- 班級(jí) -- 教師”這種經(jīng)典模式來(lái)講解自己所運(yùn)用的知識(shí)點(diǎn)??赡芫W(wǎng)友直接將我的代碼粘貼-復(fù)制,運(yùn)行會(huì)報(bào)錯(cuò)。不過(guò)其中的知識(shí)點(diǎn)確是無(wú)誤的!
? ? ? ? 在本篇文章中,最重要的是其運(yùn)用到SQL Server表值類型變量這塊知識(shí)。關(guān)于在Java代碼中引入的Sql Server-Jar包,不能太低,否則無(wú)法使用“表值類型變量”這塊知識(shí)。?
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 {
/**
* 批量提交班級(jí)信息
*/
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 ?, ?");
// 設(shè)置存儲(chǔ)過(guò)程中所用的臨時(shí)表名
SQLServerDataTable sourceDataTable = new SQLServerDataTable();
// 為臨時(shí)表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);
// 可一次性將多個(gè)不同學(xué)生插入到同一個(gè)班級(jí)中
for (Student student : clazz.getStudent()) {
// 將數(shù)據(jù)添加進(jìn)創(chuàng)建的Table表中
sourceDataTable.addRow(clazz.getTeacher(), clazz.getClaNo(),
student.getSex(), student.getName(),
student.getAge(), student.getStuNo());
}
// 字符串"clazz_Table"為調(diào)用數(shù)據(jù)庫(kù)存儲(chǔ)過(guò)程“proc_test01”中,其內(nèi)部編寫的臨時(shí)表名稱
cs.setStructured(1, "clazz_Table", sourceDataTable);
cs.registerOutParameter(2, java.sql.Types.INTEGER); // 可返回值的參數(shù)
return cs;
}
},
new CallableStatementCallback() {
@Override
public Integer doInCallableStatement(CallableStatement cs) throws SQLException, DataAccessException {
cs.execute();
return cs.getInt(2); // 將第“2”個(gè)參數(shù)的值返回。第“2”個(gè)參數(shù),其類型是“返回值類型參數(shù)”
}
}
);
count = testCount; // 將testCount變量賦值給count變量
return count;
} // public int putClazz(Clazz clazz)
}
Student.java類(學(xué)生類),其代碼如下
package com.entity;
public class Student {
private char sex; // 性別
private String name; // 姓名
private int age; // 年齡
private int stuNo; // 學(xué)號(hào)
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類(班級(jí)類)
package com.entity;
import java.util.List;
public class Clazz {
private String teacher; // 班主任
private String claNo; // 班級(jí)編號(hào)
private List stuList; //學(xué)生
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 getStuList() {
return stuList;
}
public void setStuList(List stuList) {
this.stuList = stuList;
}
}
--------------------------------------------------------------------------
--------------------------------------------------------------------------
例如,寫一接口,調(diào)用putClazz()函數(shù),則可傳遞一組JSON數(shù)據(jù),其數(shù)據(jù)格式如下所示。通過(guò)調(diào)用putClazz()函數(shù),可以做到在一次提交數(shù)據(jù)過(guò)程中:一個(gè)班級(jí)可以插入多個(gè)學(xué)生信息。
JSON格式代碼:
{
"teacher": "吳老師",
"clano": "打雜1班",
"stuList": [
{
"sex": "男",
"name": "吃瓜群眾",
"age": 18,
"stuNo": 101001
},
{
"sex": "女",
"name": "如花",
"age": 16,
"stuNo": 101002
},
{
"sex": "女",
"name": "齙牙珍",
"age": 20,
"stuNo": 101001
}
]
}