mybatis存在就不插入_mybatis批量插入失败的问题

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

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注入。

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

一般能用#的就别用$.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值