MyBatis 动态 SQL
动态 SQL 是 MyBatis 的一个强大特性。在编写 SQL 语句时,尝尝需要根据不同条件拼接 SQL 语句,动态 SQL 帮助开发者非常轻松地实现各种条件下的 SQL 拼接。
下面是 MyBatis 提供的基于 OGNL 的动态 SQL 表达式。
- if
- choose (when, otherwise)
- trim (where, set)
- foreach
1. if 语句
动态 SQL 中一个常见做法是有条件包含 where 子句。
示例:
<select id = "getByName" parameterType = "User" resultType = "User"> SELECT * FROM User <if test = "name != null"> WHERE name LIKE #{name} </if> </select>
此语句查询用户列表,如果提供了用户名称,则根据用户名(like 匹配)查询用户。
可以包含多个 if 条件,如下所示:
<select id = "getByName" parameterType = "User" resultType = "User"> SELECT * FROM User <if test = "name != null"> WHERE name LIKE #{name} </if> <if test = "id != null"> AND id = #{id} </if> </select>
2. choose, when, otherwise 语句
MyBatis 提供了一个 <choose> 标签,类似 Java 的 switch 语句,可以在多个选项中只选择一个生效。
下面的示例,如果 name 不为空,根据 name 查询用户,如为空,接着判断下一个条件:如果 id 不为空,根据 id 查询用户,如果都不满足进入 otherwise 分支。
<select id = "getByNameOrId" parameterType = "User" resultType = "User"> SELECT * FROM User <choose> <when test = "name != null"> WHERE name LIKE #{name} </when> <when test = "id != null"> WHERE id = #{id} </when> <otherwise> WHERE 1 </otherwise> </choose> </select>
3. where, set 语句
看前面的例子:
<select id = "getByName" parameterType = "User" resultType = "User"> SELECT * FROM User <if test = "name != null"> WHERE name LIKE #{name} </if> <if test = "id != null"> AND id = #{id} </if> </select>
如果前一个条件不满足,后面条件满足,生成的sql语句是错的,如下所示:
SELECT * FROM User AND id = xxx
mybatis的<where>标签可解决此类问题:
<select id = "getByName" parameterType = "User" resultType = "User"> SELECT * FROM User <where> <if test = "name != null"> name LIKE #{name} </if> <if test = "id != null"> AND id = #{id} </if> </where> </select>
<where>标签只在标签内至少有一个条件成立时才插入 where,另外,如果内容以 AND 或 OR 开头,MyBatis 会自动去掉 AND 与 OR。
类似 <where>,动态更新时可以使用 <set>,<set> 标签可以用于动态包含需要更新的列。
示例:
<update id="updateAuthorIfNecessary"> update Author <set> <if test="username != null">username=#{username},</if> <if test="password != null">password=#{password},</if> <if test="email != null">email=#{email},</if> <if test="bio != null">bio=#{bio}</if> </set> where id=#{id} </update>
4. foreach 语句
foreach 的主要作用是遍历一个集合构建 in 条件。例如,有一个用户 List,可以通过 foreach 遍历 List 获取所有用户 id 作为 in 条件。
foreach 标签的属性主要有 item,index,collection,open,separator,close。
- item 表示遍历集合时的当前元素(如果集合是map,item是值)
- index 表示遍历集合时的当前元素索引(如果集合是map,item是键)
- open 表示该语句开始字符串
- separator 表示语句中元素之间的分隔符
- close 表示该语句结束字符串
- collection 表示集合的类型,任何可迭代对象(如 List、Set 等)、Map 对象或者数组对象传递给 foreach 作为集合参数
<select id = "selectUserIn" resultType = "User" parameterType="java.util.List"> SELECT * FROM User WHERE id in <foreach item = "item" index = "index" collection = "list" open = "(" separator = "," close = ")"> #{item} </foreach> </select>
5. 动态 SQL 范例
1) UserMapper.xml
映射文件中添加如下代码:
... <select id="getByName" parameterType="User" resultMap="result"> SELECT * FROM User <if test="name != null"> WHERE name LIKE #{name} </if> </select> ...
2) App.Java
应用程序 main 类文件中添加如下代码:
System.out.println("------------ 动态sql获取用户 -----------"); User user3 = new User("user3"); user3 = (User) session.selectOne("User.getByName", user3); System.out.println(user3.getId()); System.out.println(user3.getName()); System.out.println("动态sql获取用户成功");
3) 运行
输出:
------------ 动态sql获取用户 ----------- 3 user3 动态sql获取用户成功
下一章:MyBatis 注解开发
MyBatis 最初配置信息是基于 XML ,映射语句(SQL)也是定义在 XML 中的。而到了 MyBatis3 提供了新的基于注解的配置。我们可以使用 XML 方式编写 SQL 映射语句,实现对数据库的增删改查操作。MyBatis 提供另外一种方式,使用 Java 注解编写 SQL 映射语句。