因mybatis的$与#号的区别而导致的bug笔记

        最近项目中有一个功能需要先根据设定字段自定义排序,然后根据排序设定导出word文档。开发时我使用freemarker已经完成功能,但还是被测试提了个bug,说我排序没有生效。本想反驳的,奈何人实锤在手,只好乖乖调试,最终找到问题并解决。下面上解决步骤,谨记谨记。哈哈!

       排序的页面长这样:

因mybatis的$与#号的区别而导致的bug笔记_第1张图片

点击排序设置后,页面如这样:

因mybatis的$与#号的区别而导致的bug笔记_第2张图片

选中根据出生日期排序并勾选逆序前复选框。

后台接口,长这样(第一个参数为主键,第二个参数为前台页面组装好的排序字段):

上面的步骤都是正常的,导致排序失败的原因就在下图:

导致排序失败错误时的mybatis的sql文件长这样:

因mybatis的$与#号的区别而导致的bug笔记_第3张图片

修改后正常运行的mybatis的sql文件长这样:

因mybatis的$与#号的区别而导致的bug笔记_第4张图片

仔细观察这两个sql文件,就能发现问题的原因了。原因就是#和$导致的。

第一个sql(错误实例)运行时,断点调试显示如下图:

因mybatis的$与#号的区别而导致的bug笔记_第5张图片

因mybatis的$与#号的区别而导致的bug笔记_第6张图片

第二个sql(正确实例)运行时,断点调试显示如下图:

       总结:对比两条sql运行的断点调试实例,我们可以发现,二者区别在于:用$号时,在mybatis编译sql的阶段,$号位置的值已经由我们传过来的参数替换,而#号位置此时是用?号代替的(这时可以看到错误的sql实例有两个问号,而正确的sql实例只有一个问号,另一个排序字段已经变成我们前台传的值了)。在实际跟数据库交互时,正确的sql实例只会传一个值(既用#号标记的主键值),而错误实例会传两个值。而且此时错误实例的order by解析为order by '前台传的排序值',外面多了一层单引号,所以排序失败。

上面的总结说的太多,不如直接来图看的清楚,上图:

 

因mybatis的$与#号的区别而导致的bug笔记_第7张图片

因mybatis的$与#号的区别而导致的bug笔记_第8张图片

最最后,实际使用过程中,如果你需要传的参数原样出现在sql中,就用$符号,否则用占位符?,关于$和#的区别,#号更安全,至于为何更安全,百度一下二者区别,度娘会告诉你,特别详细。

 

码字不易,转载请注明出处!

你可能感兴趣的:(java常见问题烂笔头)