開發項目中,老是與數據打交道,有的時候將數據放入到一個集合中,而後在遍歷集合一條一條的插入,感受效率超很差,最近又碰到這個問題,插入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