Oracle版本方案(目前只找到Oracle的解決辦法,SQL
Server的歡迎大家補充)
參考博客:Mybatis批處理
參考博客:Oracle存儲過程實現JAVA中的LIST輸入參數
說明:數據庫版本為11g,基本上除了存儲過程別的都是相對固定的格式,親測通過。
第一步:創建兩個自建類型
CREATE OR REPLACE TYPE xxxobj AS OBJECT(
aVARCHAR2(10),
bVARCHAR2(10),
cVARCHAR2(50)
);
CREATE OR REPLACE TYPE xxxtable AS TABLE OFxxxobj;
第二步:編寫存儲過程
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(說是辦法而不算是方案,這是因為其中包含了一些奇巧淫技,我是這么認為的,上不了臺面。)
好了,開始代碼,第一步也是唯一的一步:我稱之為拆分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);
}
簡單吧,其中500這個參數卻決于你的數據庫類型和你的sql對應的參數個數(SqlServer2005的傳入參數是限制2200個左右,假如你的sql要向表A(除主鍵外,3個字段)插入記錄,那這個參數就是2200除3取整。而list的subList這個方法相信你也是熟到不能再熟了。另外,insert方法是定義在mapper.xml中的方法,利用foreach標簽實現。不用擔心事務,如果報異常是會整體回滾的,前提是你配置了事務。