mybatis的批量新增

开发项目中,总是与数据打交道,有的时候将数据放入到一个集合中,然后在遍历集合一条一条的插入,感觉效率超不好,最近又碰到这个问题,插入50条数据用了将近1s,完全满足不了系统的需求.效率必须加快,然后网上查询资料,历经千万bug,终于搞定,这里指提供mybatis中的配置,至于dao层的调用mybatis就自己上网查询下资料吧

1根据网上搜了一下资料,在sql-mapper.xml文件中写了如下配置可进行批量操作

<  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[    ]]> 即可,好吧配置变成了 

<  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 这个方式
重新启动,然后继续报错,奔溃

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.
大小写不敏感,,配置如下

<  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的时候不在报这个错误了,此时配置如下

<  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.springframework.jdbc.BadSqlGrammarException:
### Error updating database.  Cause: java.sql.SQLException: ORA-01790: 表达式必须具有与对应表达式相同的数据类型

然后调试,发现VOL_A虽然是数字样子,但是我放入到map的是字符串。。。相当的无语,改成Double类型的放入到map中,然后重新调用到这个方法的时候。
看着屏幕上刷的数据,一种幸福感,满满的。。。
然后看下效率,比原来单条插入快了6倍!!!
最后想了下mybatis操作的时候#是会根据列的类型来判断是否需要添加引号,$不会加,然后将jdbcType=DOUBLE的字段换成了$,结果运行的时候没有报错。。但是数据库中相应字段没有数据啊!!!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MyBatis中进行批量新增有几种方式。 第一种方式是使用for循环进行新增。这种方式类似于之前使用Hibernate进行批量新增的方式。你可以在循环中调用insert语句,每次插入一条数据。这种方式适用于数据量较小的情况。 第二种方式是使用MyBatis批量模式进行新增。你可以通过在SqlSession中设置ExecutorType为BATCH来启用批处理模式。然后,在循环中调用mapper的插入方法,将数据对象传递给插入方法。最后,调用SqlSession的commit方法提交批量操作。这种方式会将所有的插入操作集中在一个批处理中执行,可以提高插入的效率。 第三种方式是依赖于数据库的特性,使用<foreach>标签来拼接批量插入的SQL。具体的语法和实现方式取决于使用的数据库。在MySQL中,你可以使用类似"insert into table(field1,field2,...) values ('test1','test1',...),('test2','test2',...),('test3','test3',...)..."的语法。在Oracle中,你可以使用"insert all ... select 1 from dual"的语法。这种方式适用于从无到有的新增,比如批量导入Excel数据。 引用中的Mapper的XML配置文件提供了namespace的声明,引用中的代码示例展示了使用MyBatis批量模式进行新增的测试方法。你可以参考这些配置和代码来实现MyBatis批量新增功能。123 #### 引用[.reference_title] - *1* *2* *3* [MyBatis中的批量新增](https://blog.csdn.net/hi__study/article/details/94570159)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值