Ⅰ 前言
可以看到官方文档中说,动态 SQL 是 MyBatis 最强大的特性之一,
这句话是说,如果你用过JDBC或者其他类似的框架,就会明白根据条件拼接 SQL 字符串有多痛苦。
根据条件拼接,就是比如现在传进来 5 个参数,我们就要拼接 5 个,传进来 3 个我们就要拼接 3 个,这个拼接的语句写起来是很麻烦的,要注意空格,注意符号多了少了。
MyBatis 的动态 SQL 将极大地简化我们拼装 SQL 的操作。动态 SQL 元素和使用 JSTL 或其他类似基于 XML 的文本处理器相似。
MyBatis 提供了四个标签,我们接下来逐一来看一下。
关于 MyBatis 的基本操作,请看我前面两篇文章👇
【Java Web】-> MyBatis -> Hello MyBatis -> 第一个 MyBatis 程序与配置文件详解
Ⅱ 动态 SQL
A. if 判断
还是使用 MyBatis 第二课 中的 case,我定义了一个实体类 Employee
以及配套的一些查询方法。
比如我们现在要查询一个员工,要求携带了哪个字段查询条件就带上这个字段的值。
什么意思呢?就是我们要查询一个员工,可能是根据 id
,可能是根据 firstName
,我们的要求意思就是传进来的参数是不一定的,传进来几个就使用几个参数做查询。
这就是动态 SQL 的应用,大家可以想一想,如果是原来那种写法,每次传进来的参数不一样,我们都要写不同的 SQL 语句,并且都是写死的,下次换个参数又要重写 SQL。
我们先来在接口中定义一个方法,由于有可能查询出的结果是多条记录,所以返回值使用 List
。
不用动态 SQL 的话,我们的查询语句可能就是下面这样 👇
但是我们的要求是只有用户传一个 gender
进来,我们才进行 gender
的查询,才要加上 gender
的查询语句,而现在直接就写死了。
这里需要用到动态 SQL 的一个标签 if
。
if
中有一个属性 test
,在这里要写的是一个判断表达式。比如我们要写 JSTL 的时候,在 test
中要写的 EL 表达式,而这里要写的是 OGNL 表达式。 OGNL 表达式和 EL 表达式是非常类似的。
上面这张图是对 OGNL 表达式的一个小总结,在接下来的文章中我们边用边学,掌握基本的 OGNL 表达式用法。
那么用 OGNL 写出来的判断语句就是下面这样👇
注意在 test
属性中,我写的 id,firstName 等元素都是用户传进来的参数,所以我们可以在 test
中做一个判断。
id 就是判断一下参数是不是 null,因为我写的属性是 int
类型的,不是 Integer
,所以不可能是 null
,但是这里为了逻辑完整性还是写一个判断表达式。
firstName
除了判断为不为 null
之外,我还加了一个是不是空串的判断。这里其实更建议使用 xml 的转义字符,来表示两个单引号,避免出错。
在 email
的判断中,为了体现 OGNL 的功能,我还加了一个操作就是 trim()
。这个方法在 Java 中是清除字符串的前导空格和尾部空格的。使用 OGNL 表达式我们可以直接使用这个方法。
最后再看 gender
,它是一个字符类型 char
,但是其实不管是 char
还是 String
,我们这里直接和 0
相比较,OGNL 会自动进行数字和字符串的转换。
现在我们来做个测试。
注意我这里,除了 id 属性,其他所有的参数都是不合法的。我们来做一个查询。
可以看到查询的 SQL 语句中,只有 id 一个条件。
那我们再传几个参数进去。
这次我们传递的 id、firstName 和 gender 都是有效数据。
可以看到 SQL 语句中就增加了这三个数据的查询,这就是所谓的 动态 SQL。
B. trim 截取
这里还会有个问题,在我的程序里 id 不能被输入为 null,所以安全性可以保证,但是如果我的 id 类型是 Integer,然后第一条属性不合法,会出现什么状况呢?
我们再来看一下之前写的语句。
我们写判断表达式的时候,都需要从第二个条件的语句