Oracle版本方案(目前只找到Oracle的解決辦法粱胜,SQL
Server的歡迎大家補(bǔ)充)
參考博客:Mybatis批處理
參考博客:Oracle存儲(chǔ)過(guò)程實(shí)現(xiàn)JAVA中的LIST輸入?yún)?shù)
說(shuō)明:數(shù)據(jù)庫(kù)版本為11g,基本上除了存儲(chǔ)過(guò)程別的都是相對(duì)固定的格式亡嫌,親測(cè)通過(guò)。
第一步:創(chuàng)建兩個(gè)自建類型
CREATE OR REPLACE TYPE xxxobj AS OBJECT(
aVARCHAR2(10),
bVARCHAR2(10),
cVARCHAR2(50)
);
CREATE OR REPLACE TYPE xxxtable AS TABLE OFxxxobj;
第二步:編寫存儲(chǔ)過(guò)程
CREATE OR REPLACE PROCEDURE xxxprocedure(names IN VARCHAR,xxxlist IN xxxtable )
BEGIN
FOR I IN 1..xxxlist.COUNT LOOP
INSERT INTO xxx VALUES
(
xxxlist(I).a,
xxxlist(I).b,
xxxlist(I).c
);
...
...
...
第三步:java代碼
xml文件:
{CALL xxxprocedure (?,?)}
java:編寫xxxHandler類泵额,繼承BaseTypeHandler并重寫setNonNullParameter、getArray
@SuppressWarnings("unchecked")
@Override
public voidsetNonNullParameter(PreparedStatement parameterSetter, int i, Object o,JdbcTypejdbcType) throws SQLException {
Connectionconn = null;
try {
if (null != o) {
List list= (ArrayList) o;
conn =DriverManager.getConnection("jdbc:oracle:thin:xxx", "xxx","xxx");
ARRAY array = getArray(conn,"xxxobj", "xxxtable", list);
parameterSetter.setArray(i,array);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != conn) {
conn.close();
}
}
}
@SuppressWarnings("rawtypes")
@Override
private Array setNonNullParametergetArray(Connection con, String OracleObj, String Oraclelist, List listData)throws Exception {
ARRAYarray = null;
ArrayDescriptordesc = ArrayDescriptor.createDescriptor(Oraclelist, con);
STRUCT[]structs = new STRUCT[listData.size()];
if (listData != null &&listData.size() > 0) {
StructDescriptor structdesc = newStructDescriptor(OracleObj, con);
for (int i = 0; i < listData.size();i++) {
Object[] result = {((xxxClass)listData.get(i)).getA(),((xxxClass) listData.get(i)).getB(),((xxxClass)listData.get(i)).getC()};
structs[i]= new STRUCT(structdesc, con, result);
}
array = new ARRAY(desc, con, structs);
}else{
array= new ARRAY(desc, con, structs);
}
return array;
}
---------------------------------------------------分割線----------------------------------------------------------
SqlServer版本辦法携添,兼容Oracle(說(shuō)是辦法而不算是方案嫁盲,這是因?yàn)槠渲邪艘恍┢媲梢迹沂沁@么認(rèn)為的烈掠,上不了臺(tái)面羞秤。)
好了,開始代碼左敌,第一步也是唯一的一步:我稱之為拆分list
int n=list.size();
while(n>500){
xxxMapper.insertlist.subList(0,500));
list.subList(0, 500).clear();
n=list.size();
}
if(n>0){
xxxMapper.insert(list);
}
簡(jiǎn)單吧瘾蛋,其中500這個(gè)參數(shù)卻決于你的數(shù)據(jù)庫(kù)類型和你的sql對(duì)應(yīng)的參數(shù)個(gè)數(shù)(SqlServer2005的傳入?yún)?shù)是限制2200個(gè)左右,假如你的sql要向表A(除主鍵外矫限,3個(gè)字段)插入記錄瘦黑,那這個(gè)參數(shù)就是2200除3取整京革。而list的subList這個(gè)方法相信你也是熟到不能再熟了。另外幸斥,insert方法是定義在mapper.xml中的方法匹摇,利用foreach標(biāo)簽實(shí)現(xiàn)。不用擔(dān)心事務(wù)甲葬,如果報(bào)異常是會(huì)整體回滾的廊勃,前提是你配置了事務(wù)。