美文网首页
mybatis批量插入失败的问题

mybatis批量插入失败的问题

作者: 逝去的风信子 | 来源:发表于2018-03-07 21:04 被阅读0次

    某日,同事说批量插入失败,异常如下

    2018-03-07 20:54:58,262 ERROR [][CardOperationVerifyServiceImpl.java:95] : 添加申请记录出现异常

    org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.binding.BindingException: Parameter '__frch_item_0' not found. Available parameters are [list, param1]

    at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:76)

    at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:399)

    at com.sun.proxy.$Proxy17.insert(Unknown Source)

    at org.mybatis.spring.SqlSessionTemplate.insert(SqlSessionTemplate.java:253)

    at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:52)

    at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:53)

    at com.sun.proxy.$Proxy29.batchCardOperationRecord(Unknown Source)

    at com.shitu.cloudCard.service.impl.CardOperationVerifyServiceImpl.applyMoneyUp(CardOperationVerifyServiceImpl.java:91)

    at com.shitu.service.CardOperationVerifyTest.applyMoneyUpTest(CardOperationVerifyTest.java:20)

    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

    at java.lang.reflect.Method.invoke(Method.java:483)

    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)

    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)

    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)

    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)

    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)

    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)

    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)

    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)

    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88)

    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)

    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)

    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)

    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)

    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)

    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)

    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)

    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)

    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)

    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)

    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)

    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)

    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)

    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)

    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

    Caused by: org.apache.ibatis.binding.BindingException: Parameter '__frch_item_0' not found. Available parameters are [list, param1]

    at org.apache.ibatis.binding.MapperMethod$ParamMap.get(MapperMethod.java:168)

    at org.apache.ibatis.reflection.wrapper.MapWrapper.get(MapWrapper.java:45)

    at org.apache.ibatis.reflection.MetaObject.getValue(MetaObject.java:122)

    at org.apache.ibatis.reflection.MetaObject.metaObjectForProperty(MetaObject.java:145)

    at org.apache.ibatis.reflection.MetaObject.getValue(MetaObject.java:115)

    at org.apache.ibatis.scripting.defaults.DefaultParameterHandler.setParameters(DefaultParameterHandler.java:79)

    at org.apache.ibatis.executor.statement.PreparedStatementHandler.parameterize(PreparedStatementHandler.java:85)

    at org.apache.ibatis.executor.statement.RoutingStatementHandler.parameterize(RoutingStatementHandler.java:63)

    at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:77)

    at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:48)

    at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:115)

    at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:75)

    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

    at java.lang.reflect.Method.invoke(Method.java:483)

    at org.apache.ibatis.plugin.Invocation.proceed(Invocation.java:49)

    at com.shitu.cloudCard.interceptor.SqlInterceptor.intercept(SqlInterceptor.java:137)

    at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:61)

    at com.sun.proxy.$Proxy40.update(Unknown Source)

    at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:170)

    at org.apache.ibatis.session.defaults.DefaultSqlSession.insert(DefaultSqlSession.java:157)

    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

    at java.lang.reflect.Method.invoke(Method.java:483)

    at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:386)

    ... 35 more

    这是mybatis的常见异常,随即查询xml里的sql语句,多次测试,无问题。困惑。。。

    将批量插入改成单笔插入,插入数据库成功。

    怀疑是mycat的问题,搜索之。

    SELECT:

    跨分片(实体库)的交叉查询

    跨节点的联合查询 (如用户库的表和平台库的表做联合查询)

    INSERT:

    插入的字段不包含分片字段 (如插入tbl_user_base_info表,没有提供user_id列)

    插入的分片字段找不到对应分片

    复制插入Insert into…select…

    多行插入insert into tab_a(c1,c2) values(v1,v2),(v11,v21)…

    UPDATE:

    更新的列包含分片列

    多表更新update a, b set a.nation=’China’, b.pwd=’123456’ where a.id=b.id

    复杂更新update a, b set a.nation=’China’ where a.id=b.id; 但支持子查询方式update a set a.nation=’China’ where id in (select id from b);

    DELETE:

    复杂删除 delete a from a join b on a.id=b.id;

    支持子查询方式delete from a where a.id in (select id from b), 但表不能起别名

    其它:

    Call procedure() MyCat未支持存储过程定义, 因而不允许调用存储过程,但可通过注解来调用各个分片上的存储过程

    Select func(); 不支持这种方式直接调用自定义函数,但支持select id, func() from employee,只需employee所在的所有分片上存在这个函数。MySql自带函数可随意使用。

    注意事项:

    Order by字段必须出现在select中(MyCat先将结果取出,然后排序)

    Group by务必使用标准语法select count(1),type from tab_a group by type;

    MyCat的一些自带函数sum,min,max等可以正确使用,但多分片执行的avg有bug,执行的结果是错误的谨慎使用子查询,外层查询没有分片查询条件,则会在所有分片上执行(子查询内外层的表一样较为特殊)

    随即将mybatis中的#改成$,问题解决。

    动态 SQL 是 mybatis 的强大特性之一,也是它优于其他 ORM 框架的一个重要原因。mybatis 在对 sql 语句进行预编译之前,会对 sql 进行动态解析,解析为一个 BoundSql 对象,也是在此处对动态 SQL 进行处理的。在动态 SQL 解析阶段, #{ } 和 ${ } 会有不同的表现

    select * from user where name = #{name};

    #{} 在动态解析的时候, 会解析成一个参数标记符。就是解析之后的语句是:

    select * from user where name = ?;

    那么我们使用 ${}的时候

    select * from user where name = ${name};

    ${}在动态解析的时候,会将我们传入的参数当做String字符串填充到我们的语句中,就会变成下面的语句

    select * from user where name = "dato";

    预编译之前的 SQL 语句已经不包含变量了,完全已经是常量数据了。相当于我们普通没有变量的sql了。

    综上所得, ${ } 变量的替换阶段是在动态 SQL 解析阶段,而 #{ }变量的替换是在 DBMS 中。

    这是 #{} 和 ${} 我们能看到的主要的区别,除此之外,还有以下区别:

    #方式能够很大程度防止sql注入。

    $方式无法防止Sql注入。

    $方式一般用于传入数据库对象,例如传入表名.

    一般能用#的就别用$.

    相关文章

      网友评论

          本文标题:mybatis批量插入失败的问题

          本文链接:https://www.haomeiwen.com/subject/kfmsfftx.html