当前位置: 首页 > 后端技术 > Java

为什么不建议在MyBatis中使用where1=1?

时间:2023-04-02 09:56:10 Java

最近接手了一个老项目,那种“愉悦的心情”自然是无法形容的,做开发的朋友都懂,这里就不多说了,都是泪...显然接手老项目的时候,你必须先熟悉业务代码,但是当你翻阅mapper文件时,你会发现一个相当奇怪的事情。下面是简化的业务代码:select*fromuserwhere1=1andname=#{name}andpassword=#{password}机智的小伙伴可能已经看到问题了,发现很多mapper中有相同的想象,几乎所有的mapper都包含一个无用的拼接SQL:where1=1。作为一个差不多有代码洁癖的人,我忍不住要做出一些改变。由于错误的转换方法是去掉where1=1,最简单的方法是直接从代码中删除,如下代码所示:select*fromuserwherename=#{name}andpassword=#{password}上面的代码删除了1=1,并将firstname放在queryand被删除以防止SQL查询报告错误。但这可以吗?我们直接看结果。当包含参数名查询时,结果如下:一切合乎逻辑,一团糟。但是,当省略name参数时(因为name不是必须的参数,可以省略),会触发如下异常:或者只查询password时,结果是一样的:都报错了,sowhat我应该怎么做?是否有可能恢复1=1回来?正确的提升方式其实是没有必要的。这个问题在MyBatis中已经想到了。我们可以将SQL中的where关键字替换成MyBatis中的标签,对每个标签字符进行添加拼接,这样问题就解决了,如下代码所示:select*fromuserandname=#{name}andpassword=#{password}代码改造完成后,我们来测试一下所有的请求场景。Requestswithoutanyparameters这时候我们可以不传参数(查询所有数据),如下图:生成的SQL语句如下:一个参数的请求也可以传一个参数,查询是根据名称进行查询,如下图:生成的SQL如下图:也可以只根据密码查询,如下图:生成的SQL如下图:传递两个参数的请求也可以根据name加password进行联合查询,如下图:生成的SQL如下图:使用分析我们惊喜的发现,在使用了之后tag,无论在任何查询场景下,传一个或多个参数,还是直接不传参数,都可以轻松搞定。首先,标签会判断,如果没有参数,则在sql语句中不拼接where查询,否则拼接where查询;其次,在查询的标签中,每个标签都可以加上and关键字。MyBatis会自动删除第一个条件前面的and关键字,以免造成SQL语法错误。这个在官方文档中也有说明,如下图:总结在MyBatis中,建议尽量避免使用无意义的SQL拼接where1=1,我们可以使用标签来代替where1=1,这样的写法简洁大方,何乐而不为呢?以上内容仅代表个人观点,欢迎在评论区留言讨论。关注公众号「Java中文社区」,查看更多MyBatis和SpringBoot系列文章。