当前位置:首页 > 技术文章 > 正文内容

解决mybatis动态生成sql错误的问题

arlanguage1个月前 (03-28)技术文章27

1. 问题概述

我们在使用mybatis的标签动态生成sql的时候,由于参数的不同,有可能出现生成的错误sql的问题,最常见的有以下两种:

  • where后面的and/or问题
  • update中多余的逗号问题

错误一:

 

如果name不是null或者空字符串,那么生成的sql是正常的,没有问题;如果name为null或者空字符串,那么生成的sql为:

select id,name,age from student  where and logo=?

这个sql肯定会报错,需要把“and”去掉。

错误二:


    update student
    set
    name = #{name},
    age = #{age},
    address = #{address}
where id = #{id,jdbcType=BIGINT}

如果上面三个值都不为null,那么,生成的sql语句没有任何问题,如果address为null,那么生成的语句为:

update student set name=?,age=?, where id = ?

问题很明显,where前面多了个逗号。

2. where问题的解决方法

错误一的解决方法有三种,一种是我们在很早以前(通过java拼装sql)就一直在用的方法,就是在where后加上1=1;另一种方法就是使用mybatis的标签;第三种是使用mybatis的标签。

2.1 where后加1=1

这种方法比较简单了,还是上面那个例子,可以将上面的例子改成如下方式:

我们直接在where后添加1=1,然后后面的每个if中都是用and或者or开头即可,这样,无论哪个为null,生成的sql语句都没有问题。如果全部为null,那么生成的sql为:

select id,name,age from student where 1=1

2.2 使用where标签

标签的作用是只有在子元素返回内容的情况下才会插入where子句(也就是说如果where标签没有任何子元素,那么where将不会被拼接到sql中),除此之外,它还有一个功能就是如果字句以and或者or开头,将会被自动除去。上面的例子使用where标签修改为:

 
  • 如果name为null,age不为null,将会生成where子句,但是age中是以and开头的,and将会被去掉。sql为:
select id,name,age from student where age=?
  • 如果name和age都为null,将不会生成where子句,sql为:
select id,name,age from student

2.3 使用trim标签

标签的作用主要是在它所包含的内容上添加前缀、后缀,删除它所包含内容的前缀、后缀。主要包含以下几个属性:

  • prefix:在所包含的内容上添加指定的前缀。
  • suffix:在所包含的内容上添加指定的后缀。
  • prefixOverrides:删除所包含内容指定的前缀。
  • suffixOverrides:删除所包含元素指定的后缀。

现在使用trim标签来改造错误一中的问题,如下:

在上面的配置中,如果name为null,而age不为null,如果没有trim,生成的sql为:

select id,name,age from student  and age=?

由于trim中prefix="where"的作用,将会添加where前缀,也就是:

select id,name,age from student where  and age=?

由于trim中prefixOverrides="and"的作用,将会去除开头的and,也就是:

select id,name,age from student where   age=?

如果说name和age都是null,会出现什么情况?标签和标签一样,如果不包含任何内容,那么,prefix和suffix都不会插入任何东西。

还有一点需要注意,那就是如果prefixOverrides或者suffixOverrides如果包含多个元素,用“|”分隔,例如:


  ...

并且AND和OR后面的空格是必须的。

3. update问题的解决方法

错误二的解决方法有两种,一种是通过<set>标签来解决;另一种也是通过标签来解决。

3.1 使用set标签

set标签的作用和where标签的作用类似,主要有两个:

  • 在包含的内容前面插入set标签。
  • 删除掉额外的逗号。

我们使用set标签改造错误二的配置,如下:


    update student
    <set>
        name = #{name},
        age = #{age},
        address = #{address}
    </set>
    
where id = #{id,jdbcType=BIGINT}

如果address为null而其他不为null,在没有set标签的情况下,sql语句为:

update student set name=?,age=?, where id = ?

在使用set标签的情况下,会自动去除语句中多余的逗号,就生成了正确的sql:

update student set name=?,age=? where id = ?

3.2 使用trim标签

和问题一类似,问题二也可以使用trim标签来解决,改造完如下:


    update student
    
        name = #{name},
        age = #{age},
        address = #{address}
    
where id = #{id,jdbcType=BIGINT}

prefix="set"将在包含内容不为空的情况下添加“set”,suffixOverrides=","将删除尾部的“,”,从而生成了正确的sql语句。

4. 总结

标签:

  • 标签包含内容不为空的情况下,在内容的开头添加where子句。
  • 如果返回的内容是以and或者or开头,将自动删除掉。

<set>标签:

  • <set>标签包含内容不为空的情况下,在内容的开头添加set子句。
  • 自动删除掉包含内容结尾的逗号。

标签:

  • prefix:在所包含的内容上添加指定的前缀。
  • suffix:在所包含的内容上添加指定的后缀。
  • prefixOverrides:删除所包含内容指定的前缀。
  • suffixOverrides:删除所包含元素指定的后缀。

扫描二维码推送至手机访问。

版权声明:本文由AR编程网发布,如需转载请注明出处。

本文链接:http://www.arlanguage.com/post/3649.html

分享给朋友:

“解决mybatis动态生成sql错误的问题” 的相关文章

16《Nginx 入门教程》Nginx防盗链配置

百度百科的解释如下:盗链是指服务提供商自己不提供服务的内容,通过技术手段绕过其它有利益的最终用户界面(如广告),直接在自己的网站上向最终用户提供其它服务提供商的服务内容,骗取最终用户的浏览和点击率。受益者不提供资源或提供很少的资源,而真正的服务提供商却得不到任何的收益。盗链在如今的互联网世界无处不在...

Nginx高级篇:从原理到实战,彻底搞懂Nginx

推荐阅读:2020年后想跳槽?MQ、ZK、Nginx、Kafk等分布式技术你都掌握了?手撕分布式技术:限流、通讯、缓存,全部一锅端走送给你惨败阿里,洒泪复习25天,我还能抓住2019的小尾巴上岸网易?微服务架构之春招总结:SpringCloud、Docker、Dubbo与SpringBoot通过配置...

服务器不能正常关机和重启是怎么回事?

服务器不能正常关机和重启是怎么回事?服务器无法正常关机或重启可能是由多种原因引起的,涉及操作系统、硬件、应用程序和配置设置等方面。以下是详细的原因分析及对应的解决方案。一、服务器无法关机/重启的常见原因1. 操作系统问题(1)系统进程未正常终止某些进程或服务在关机时未能按预期停止,导致系统卡在关机或...

基于 consul + nginx 的Spring boot微服务集群部署

consul + nginx 负载均衡最近做的基于consul的微服务项目,仅仅在单机上部署了一套,压测的时候扛不住(并发太高的时候linux文件连接数超过上限),于是想办法搞个集群部署。最终在我们的服务器的三台机器(mirage05-mirage07)上完成部署。一. 背景介绍以及项目现状1. c...

Nginx——location常见配置指令,alias、root、proxy_pass

1、【alias】——别名配置,用于访问文件系统,在匹配到location配置的URL路径后,指向【alias】配置的路径。如: location /test/ { alias/first/second/img/; }即:请求/test/1.jpg(省略了协议与域名),将会返回文件/first...

IT30:中台/软件开发团队40人员配置

业务中台40人开发团队配置1、架构师:1名2、开发经理:1名3、开发主管:1名4、前端开发:7名5、后端开发:14名6、DBA:2名7、测试人员:4名8、UI人员:3名9、BA业务顾问:5名架构师 1名任职要求:1. 主导团队技术方向,主导项目技术方向及技术分享;2. 精通高可用互联网架构设计及管理...