mybatis批量分批次插入oracle資料庫,報ORA-01745: 無效的主機/繫結變數名...
方法一:迴圈呼叫插入單條記錄的方法,效率真心讓人捉急 (3萬條資料,快三分鐘)
public int saveGwghidlist1(List<Gwghid> list) { int xh=0; deleteGwghidByCondition(""); if(list.size()>0){ for (Gwghid gwghid: list) { xh++; gwghidDAO.saveGwghid(gwghid); System.out.println(xh); } } return xh; }
方法二:在mapper.xml中迴圈插入<foreach> (可行,但是要要分批插入,因為oracle,有sql限制64k?不確定哈)
serviceimpl
public int saveGwghidlist(List<Gwghid> list) { int xh=0; deleteGwghidByCondition(""); if(list.size()>0){ for (Gwghid gwghid: list) { xh++; gwghidDAO.saveGwghid(gwghid); System.out.println(xh); } } return xh; }
mapper.xml
<insert id="saveListGwghid" parameterType="java.util.List"> insert into GWGHID (<include refid="bf" />) select S_GWGHID.nextval,a.* from ( <foreach collection="list" item="item" index="index" separator="union all" > select #{item.wlbm,jdbcType=VARCHAR}, #{item.wlms,jdbcType=VARCHAR}, #{item.dlms,jdbcType=VARCHAR}, #{item.zlms,jdbcType=VARCHAR}, #{item.xlms,jdbcType=VARCHAR}, #{item.tzbm,jdbcType=VARCHAR}, #{item.kzms,jdbcType=VARCHAR}, #{item.kzmszt,jdbcType=VARCHAR}, #{item.jsgfsid,jdbcType=VARCHAR}, #{item.gdidzt,jdbcType=VARCHAR}, #{item.lx,jdbcType=VARCHAR}, #{item.bz,jdbcType=VARCHAR}, #{item.fbsj,jdbcType=TIMESTAMP}, #{item.color,jdbcType=VARCHAR}, #{item.drsj,jdbcType=TIMESTAMP}, #{item.xh,jdbcType=NUMERIC}, #{item.bs,jdbcType=NUMERIC} from dual </foreach> ) a </insert>
終於按照要求把maper.xml寫好了,接下來測試吧,結果嗚嗚~~~~~資料量超過2萬就報錯。
剛開始,需打印出每次插入的返回值,一直報 TOMCAT記憶體溢位問題Exception in thread ""http-bio-8080"-exec-6 問題,後來檢視
MyEclipse中開啟window-->preferences-->Tomacat -->jdk 加入了這句話,再次批量插入返回值打印出來了。
-Xms128m -Xmx512m -XX:PermSize=128m -XX:MaxPermSize=128m
再次匯入三萬條測試,
報 oracle ORA-01745: 無效的主機/繫結變數名
查了不少資料,主要原因有兩種:
1.繫結變數用了oracle關鍵字導致的 2.繫結變數中間少了分割符導致的
仔細審查了一遍mapperx.xml發現並沒有上邊兩種情況,抓狂啊
也會報這個錯 java.sql.SQLException: code [17410]無法從套接字讀取更多的資料 (自行百度,說是要改資料庫,表空間自動擴充套件的值,按照要求改了,確實不報這個錯了,改報上邊的錯了,好吧,我也是夠了)
再次開啟搜尋模式,看到了一篇文章(連結忘哈),上邊說是插入的資料量過大,超過oracle64k限制,用批次插入方式。
說幹就幹吧,批次插入一次插入1000條,因為專案需求,採用這種簡單方式即可
serviceimpl
@Override
public int saveBatGwckjg(List<Gwckjg> list) {
int xh=0;
gwckjgDAO.deleteAllGwckjg();
List<Gwckjg> insertList =new ArrayList<Gwckjg>();
for (Gwckjg gwckjg : list) {
insertList.add(gwckjg);
if(insertList.size() ==1000){
xh +=gwckjgDAO.saveBatGwckjg(insertList);
insertList.clear();
//System.out.println(xh);
}
}
if(insertList.size()>0){
int k=gwckjgDAO.saveBatGwckjg(insertList);
System.out.println(k+"ok");
}
return xh;
}
測試,完美執行,三萬條,時間35秒左右。(加上匯入驗證15秒左右,實際上就20左右的樣子)。
至此結束,睡覺去了。