关于mybatis批量更新操作的相关注意事项


前两天写的博客是mybatis的批量更新的操作 今天写一下mybatis的批量更新的相关注意事项

首先 , 本篇文章采用的是比较耗时的方法 ,但是也是比较通用的,

首先 要进行mybatis的批量操作 先要开启批量 也就是在jdbc 连接信息的URL 后面加上&allowMultiQueries=true

这是dao 方法

int updateAllList(List<Map<String, Object>> list);

因为最近一直在做通用的表单和工作模块,所以并不知道数据是什么格式的所以我的sql这么写的

  <update id="updateAllList" parameterType="java.util.List" >
  
  <foreach collection="list" item="maps"  separator=";">
  		update ${maps['tableName']} set
  			<foreach collection="maps.keys" item="k" separator=",">
  				<if test="k != 'tableName' and k != 'id' and k != 'createTime' and maps[k] != null">
  					${k} = #{maps[${k}]}
  				</if>
  			</foreach>
  		where id = ${maps['id']}
  
  </foreach>
  	
  </update>
因为我的数据是封装在map里面的 我遍历map的方式也是上面写的那样 一直没出过错 但是!! 这种
${k} = #{maps[${k}]}
的遍历方式在批量更新的操作上失效了

具体报错信息如下:

org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.binding.BindingException: Parameter 'maps' not found. Available parameters are [list, collection]
	at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:77)
	at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:446)
	at com.sun.proxy.$Proxy16.update(Unknown Source)
	at org.mybatis.spring.SqlSessionTemplate.update(SqlSessionTemplate.java:294)
	at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:55)
	at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:53)
	at com.sun.proxy.$Proxy17.updateAllList(Unknown Source)
	at com.yinsheng.service.impl.WorkServiceImpl.compute(WorkServiceImpl.java:1277)
	at com.yinsheng.controller.WorkController.compute(WorkController.java:965)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:606)
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137)
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:777)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:706)
	//后面的就省略了 也没啥用 

看到这个错误我以为是我的SQL写的有问题 我把sql打印到控制台后发现一点问题没有 然后我又怀疑 是因为双重foreach的原因 导致我第二个循环中的maps没有读出来

然后经过测试 发现并不是我的sql有问题 而是因为 :

mybatis 在进行批量更新操作的时候  sql不能用#  原因是因为 批量更新时 mybatis 会先把sql全部都拼接好 直接在数据库中运行 而使用# 的方式的话

就相当于一个站位符  是 ? 的效果 所以数据库无法识别

所以sql的拼接得用${}  的方式来进行

${k} = ${maps[k]}


这是一个重要的一点

然后我更改了sql 后 又出现了新的问题


扫描二维码关注公众号,回复: 9928681 查看本文章
Unknown column '????°‘?–?' in 'field list'

搞得我一脸懵逼 ,  因为我不经常使用${}  来拼接sql 所以很容易忽略一个问题 就是#{} 回自动帮你的数据两端加上' ' 单引号 但是 ${}  是原样输出的

所以我们使用${}  的时候要在数据两端加上' '


  <update id="updateAllList" parameterType="java.util.List" >
  
  <foreach collection="list" item="maps"  separator=";">
  		update ${maps['tableName']} set
  			<foreach collection="maps.keys" item="k" separator=",">
  				<if test="k != 'tableName' and k != 'id' and k != 'createTime' and maps[k] != null">
  					${k} = '${maps[k]}'
  				</if>
  			</foreach>
  		where id = ${maps['id']}
  
  </foreach>
  	
  </update>


以上就是 参数是list嵌套map  怎么进行mybatis的批量更新操作 当然这是很耗时的

这里有一篇关于mybatis的优化后的批量更新操作]

https://my.oschina.net/ckanner/blog/338515

大家可以参考一下



发布了16 篇原创文章 · 获赞 21 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/q690080900/article/details/77532796