您现在的位置是:网站首页 > 代码编程 > JAVA开发JAVA开发
【原】mybatis的if判断条件将字符串解析成了数字
不忘初心 2019-04-22 围观() 评论() 点赞() 【JAVA开发】
简介:mybatis的if判断条件中,默认进行数据转换时,会将字符串解析成了数字,所以我们需要将传递参数的单双引号更换一下来解决这个问题。
mybatis可以帮我们自动映射字段,在mapper.xml文件中,我们可以不用去写jdbcType来明确指定数据类型,它会自动解析成相对应的java数据类型,每次在使用了mybatis-generator之后,出于强迫症,我还主动将默认生成的jdbcType给去掉了,一直没出过问题,今天却碰到了一个问题:
出问题的业务场景中,需要根据不同的角色查询不同的订单数据,所以我就直接将角色ID当做参数传递进来,由于有多个角色的情况,所以直接将角色ID拼接成字符串,并用逗号分隔开。
mapper接口:
List<String> getOwnAssignedOrderNo(@Param("backendId") String backendId, @Param("role") String role);
mapper文件:
<if test="role == '1'">
AND w.backend_id = #{backendId}
AND w.workflow_type = 'manual_check'
</if>
<if test="role == '2' || role == '3' || role == '2,3'">
AND w.backend_id = #{backendId}
AND w.workflow_type = 'phone_check'
</if>
<if test="role == '1,2' || role == '1,3' || role == '1,2,3'">
AND w.backend_id = #{backendId}
AND (w.workflow_type = 'manual_check' OR w.workflow_type = 'phone_check')
</if>
大家注意看我这里的写法,算得上是中规中矩,role参数已经明确指定了string类型,而且在if条件中,我并没有什么特殊的写法,结果却悲剧了:
Caused by: org.apache.ibatis.exceptions.PersistenceException:
### Error querying database. Cause: java.lang.NumberFormatException: For input string: "2,3"
### Cause: java.lang.NumberFormatException: For input string: "2,3"
at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:150)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:141)
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:498)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:434)
... 140 common frames omitted
Caused by: java.lang.NumberFormatException: For input string: "2,3"
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:2043)
at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
at java.lang.Double.parseDouble(Double.java:538)
at org.apache.ibatis.ognl.OgnlOps.doubleValue(OgnlOps.java:242)
at org.apache.ibatis.ognl.OgnlOps.compareWithConversion(OgnlOps.java:99)
at org.apache.ibatis.ognl.OgnlOps.isEqual(OgnlOps.java:142)
at org.apache.ibatis.ognl.OgnlOps.equal(OgnlOps.java:794)
at org.apache.ibatis.ognl.ASTEq.getValueBody(ASTEq.java:52)
at org.apache.ibatis.ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212)
at org.apache.ibatis.ognl.SimpleNode.getValue(SimpleNode.java:258)
at org.apache.ibatis.ognl.Ognl.getValue(Ognl.java:494)
at org.apache.ibatis.ognl.Ognl.getValue(Ognl.java:458)
at org.apache.ibatis.scripting.xmltags.OgnlCache.getValue(OgnlCache.java:44)
at org.apache.ibatis.scripting.xmltags.ExpressionEvaluator.evaluateBoolean(ExpressionEvaluator.java:32)
at org.apache.ibatis.scripting.xmltags.IfSqlNode.apply(IfSqlNode.java:34)
at org.apache.ibatis.scripting.xmltags.MixedSqlNode.apply(MixedSqlNode.java:33)
at org.apache.ibatis.scripting.xmltags.TrimSqlNode.apply(TrimSqlNode.java:55)
at org.apache.ibatis.scripting.xmltags.MixedSqlNode.apply(MixedSqlNode.java:33)
at org.apache.ibatis.scripting.xmltags.DynamicSqlSource.getBoundSql(DynamicSqlSource.java:41)
at org.apache.ibatis.mapping.MappedStatement.getBoundSql(MappedStatement.java:292)
at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:81)
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:498)
at org.apache.ibatis.plugin.Invocation.proceed(Invocation.java:49)
at com.github.pagehelper.SqlUtil._processPage(SqlUtil.java:247)
at com.github.pagehelper.SqlUtil.processPage(SqlUtil.java:229)
at com.github.pagehelper.PageHelper.intercept(PageHelper.java:118)
at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:61)
at com.sun.proxy.$Proxy349.query(Unknown Source)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:148)
... 146 common frames omitted
错误非常的熟悉,类型转换异常,而且定位到了我的role参数上,一开始让我很费解,难道不能用数字类型的字符串做过参数?
以为需要对mybatis做什么特殊的配置,但是后来去其他项目比对了一下,并没有什么不一样,又跑去百度了一波,看到有人提到说没有指定jdbcType导致的,但是我这个不是字段,而是在if条件中,没办法指定jdbcType。
继续查资料,看到有大佬给了一种写法,需要对if条件中的参数做toString(),写法如下:
<if test="role == '1'.toString()">
AND w.backend_id = #{backendId}
AND w.workflow_type = 'manual_check'
</if>
<if test="role == '2'.toString() || role == '3'.toString() || role == '2,3'.toString()">
AND w.backend_id = #{backendId}
AND w.workflow_type = 'phone_check'
</if>
<if test="role == '1,2'.toString() || role == '1,3'.toString() || role == '1,2,3'.toString()">
AND w.backend_id = #{backendId}
AND (w.workflow_type = 'manual_check' OR w.workflow_type = 'phone_check')
</if>
不是我说,这种写法真的是很烦,判断条件简单还好说,如果复杂的条件,岂不是要写到吐血,遂继续百度之,终于找到了一种简单的写法:单引号和双引号调换一下
<if test='role == "1"'>
AND w.backend_id = #{backendId}
AND w.workflow_type = 'manual_check'
</if>
<if test='role == "2" || role == "3" || role == "2,3"'>
AND w.backend_id = #{backendId}
AND w.workflow_type = 'phone_check'
</if>
<if test='role == "1,2" || role == "1,3" || role == "1,2,3"'>
AND w.backend_id = #{backendId}
AND (w.workflow_type = 'manual_check' OR w.workflow_type = 'phone_check')
</if>
这样就舒服多了,不用每个if条件中都写toString(),而且问题也解决了!
此问题的出现,可以说完全是平时不注意细节所致,在项目中,我之前是有看到过同事这样写过,当时还纳闷儿为什么要将单双引换着用,强迫症的我甚至还差点儿手贱改了人家的代码,想要帮人家改邪归正,现在回想起来还真的是肤浅、无知~
方法总结:
1、如果在传参字段中,可以考虑追加jdbcType属性来指定数据类型;
2、如果在if条件中,用字符串比对的的地方少,可以直接在字符串后面跟一个toString()方法;
3、如果在if条件中,用字符串比对的地方多,直接将单引和双引调换位置;
综合考虑,尽量使用第三种写法,简单实用!
看完文章,有任何疑问,请加入群聊一起交流!!!
很赞哦! ()
相关文章
- mybatis中foreach的变量名和if的变量名相同
- springmvc + spring + mybatis整合搭建图文教程
- mybatis-generator代码自动生成插件的使用图文教程
- Mybatis调用MySQL存储过程图文教程
- 使用mybatis-generator自动生成mapper失败
- IntelliJ IDEA去掉mybatis映射mapper文件的背景色
- SSM框架基础整合搭建图文教程
- mybatis整合ehcache配置二级缓存
- springboot项目提示“Failed to determine a suitable driver class”
- ehcache警告“diskStorePath is already used by an existing CacheManager”
标签云
猜你喜欢
- IntelliJ IDEA 2019.2已经可以利用补丁永久破解激活了
- IntelliJ IDEA 2019.3利用补丁永久破解激活教程
- IntelliJ IDEA高版本最灵活的永久破解激活方法(含插件激活,时长你说了算)
- Jetbrains全家桶基于ja-netfilter的最新破解激活详细图文教程
- IntelliJ IDEA 2022.1永久破解激活教程(亲测可用,持续更新)
- 分享几个正版 IntelliJ IDEA 激活码(破解码、注册码),亲测可用,持续更新
- ja-netfilter到底需不需要mymap,2021.3.2版本激活失效?
- 如何激活idea2022.1及以上版本中的插件(亲测可用)
- 【史上最全】IntelliJ IDEA最新2022.1版本安装和激活视频教学(含插件)
- IntelliJ IDEA 2022.2 版本最新2099年永久激活方法,亲测可用,也可以开启新UI了。
站点信息
- 网站程序:spring + freemarker
- 主题模板:《今夕何夕》
- 文章统计:篇文章
- 标签管理:标签云
- 微信公众号:扫描二维码,关注我们