开发项目中,老是与数据打交道,有的时候将数据放入到一个集合中,而后在遍历集合一条一条的插入,感受效率超很差,最近又碰到这个问题,插入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