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 映射语句。
AI 中文社