[置頂] mybatis的批量新增

開發項目中,老是與數據打交道,有的時候將數據放入到一個集合中,而後在遍歷集合一條一條的插入,感受效率超很差,最近又碰到這個問題,插入50條數據用了將近1s,徹底知足不了系統的需求.效率必須加快,而後網上查詢資料,歷經千萬bug,終於搞定,這裏指提供mybatis中的配置,至於dao層的調用mybatis就本身上網查詢下資料吧java

1根據網上搜了一下資料,在sql-mapper.xml文件中寫了以下配置可進行批量操做spring

< insert id ="insertBatch" parameterType="List" >
    insert into REAL_DATA_HW(
M_LINE_NO,M_TIME,HW_NUM, VOL_A,VOL_B,VOL_C )
    values
    < foreach collection ="list" item ="item" index ="index" separator =",">
       (
#{obj.M_LINE_NO},to_date(#{obj.M_TIME},'yyyy-MM-dd hh24:mi:ss'),#{obj.HW_NUM},
       #{obj.VOL_A},#{obj.VOL_B},#{obj.VOL_C} )
    </ foreach >
</ insert >

而後啓動,調用這個操做的時候報錯
Error setting null parameter. Most JDBC driversrequire that the JdbcType must be specified for all nullable parameters. Cause:java.sql.SQLException: 無效的列類型
上網繼續查詢說加上 <![CDATA[    ]]> 便可,好吧配置變成了
sql

< insert id ="insertBatch" parameterType="List" >
<![CDATA[
    insert into REAL_DATA_HW(
M_LINE_NO,M_TIME,HW_NUM, VOL_A,VOL_B,VOL_C )
    values
]]>
    < foreach collection ="list" item ="item" index ="index" separator =",">
       (
#{obj.M_LINE_NO},to_date(#{obj.M_TIME},'yyyy-MM-dd hh24:mi:ss'),#{obj.HW_NUM},
       #{obj.VOL_A},#{obj.VOL_B},#{obj.VOL_C} )
    </ foreach >
</ insert >

而後依然報一樣的錯,查來查去,發現一句坑爹的話這個只是支持mySQL,去年買了個表。。。
繼續找方法吧,又被我找到一種在ORACLE中能夠用的方法,參考網上的步驟,有了以下的配置 數據庫

< insert id ="insertBatch" parameterType="List" >
    insert into REAL_DATA_HW(
M_LINE_NO,M_TIME,HW_NUM, VOL_A,VOL_B,VOL_C )
    < foreach collection ="list" item ="item" index ="index" separator ="union all">
     select   
#{obj.M_LINE_NO},to_date(#{obj.M_TIME},'yyyy-MM-dd hh24:mi:ss'),#{obj.HW_NUM},
       #{obj.VOL_A},#{obj.VOL_B},#{obj.VOL_C} from dual
    </ foreach >
</ insert >

這個的原理應該是參考的insert into  tableName select 。。。 from tableName1 這個方式
從新啓動,而後繼續報錯,奔潰apache

org.springframework.jdbc.UncategorizedSQLException: Error setting null parameter. Most JDBC drivers require that the JdbcType must be specified for all nullable parameters...哎 ,找緣由,mybaties對null缺少處理,須要在字段後加上jdbcType=類型,因而添加類型吧,順帶去網上查詢了mybatis的類型
iBatis官方的說法是, 只要是JDBC提供的JdbcType類中所定義的常量字符串,jdbcType這個屬性就能夠取這個值,雖然有一些類型iBatis尚且不能支持(例如blobs)。而JdbcType類則由不一樣的JDBC Driver提供,可能因爲Driver(不一樣類型的數據庫有不一樣的Driver)的不一樣會存在差別,不過大同小異。通常都支持以下類型(大小寫不敏感):
Array, BigInt, Binary, Bit, Blob, Boolean, Char, Clob, Datalink, Date, Decimal,
Double, Float, Integer, LongVarBinary, LongVarChar, Numeric, Real, Ref, SmallInt, Struct, Time, Timestamp, TinyInt, VarBinary, VarChar.
大小寫不敏感,,配置以下
mybatis

< insert id ="insertBatch" parameterType="List" >
    insert into REAL_DATA_HW(
M_LINE_NO,M_TIME,HW_NUM, VOL_A,VOL_B,VOL_C )
    < foreach collection ="list" item ="item" index ="index" separator ="union all">
     select   
#{obj.M_LINE_NO,jdbcType= VarChar },to_date(#{obj.M_TIME ,jdbcType= VarChar },'yyyy-MM-dd hh24:mi:ss'),#{obj.HW_NUM , jdbcType=Double },
       #{obj.VOL_A ,jdbcType= Double },#{obj.VOL_B ,jdbcType= Double },#{obj.VOL_C ,jdbcType= Double } from dual
    </ foreach >
</ insert >

調用的時候繼續報錯,有一個是
org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.builder.BuilderException: Error resolving JdbcType. Cause: java.lang.IllegalArgumentException: No enum const class org.apache.ibatis.type.JdbcType.Double
親,不敏感你妹!!!!!!!!!
因而慢慢替換了下Double,終於在Double寫成DOUBLE的時候不在報這個錯誤了,此時配置以下
app

< insert id ="insertBatch" parameterType="List" >
    insert into REAL_DATA_HW(
M_LINE_NO,M_TIME,HW_NUM, VOL_A,VOL_B,VOL_C )
    < foreach collection ="list" item ="item" index ="index" separator ="union all">
     select   
#{obj.M_LINE_NO,jdbcType= VARCHAR },to_date(#{obj.M_TIME ,jdbcType= VARCHAR },'yyyy-MM-dd hh24:mi:ss'),#{obj.HW_NUM , jdbcType=DOUBLE },
       #{obj.VOL_A ,jdbcType= DOUBLE },#{obj.VOL_B ,jdbcType= DOUBLE },#{obj.VOL_C ,jdbcType= DOUBLE } from dual
    </ foreach >
</ insert >

啓動,調用這個方法的依然報錯。。。
ui

org.springframework.jdbc.BadSqlGrammarException:
### Error updating database.  Cause: java.sql.SQLException: ORA-01790: 表達式必須具備與對應表達式相同的數據類型

而後調試,發現VOL_A雖然是數字樣子,可是我放入到map的是字符串。。。至關的無語,改爲Double類型的放入到map中,而後從新調用到這個方法的時候。
看着屏幕上刷的數據,一種幸福感,滿滿的。。。
而後看下效率,比原來單條插入快了6倍!!!
最後想了下mybatis操做的時候#是會根據列的類型來判斷是否須要添加引號,$不會加,而後將jdbcType=DOUBLE的字段換成了$,結果運行的時候沒有報錯。。可是數據庫中相應字段沒有數據啊!!!!!
spa

相關文章
相關標籤/搜索