1: 动态sql
动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。
利用动态 SQL,可以彻底摆脱这种痛苦,常用的标签如下
if
choose (when, otherwise)
trim (where, set)
foreach
1.1 if 使用动态 SQL 最常见情景是根据条件包含 where 子句的一部分
public void testIf(){
String userName = "如花";
UserService userService = new UserServiceImpl();
List<User> userList = userService.queryUserByName(userName);
System.out.println(userList);
userName = "";
userList = userService.queryUserByName(userName);
System.out.println(userList);
}
接口
List<User> queryUserByName(String userName);
实现类
public List<User> queryUserByName(String userName) {
SqlSession sqlSession = SqlSessionUtil.getSqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
return userMapper.queryUserByName(userName);
}
Mapper 接口
List<User> queryUserByName(@Param("userName") String userName);
mapper.xml 配置
<select id="queryUserByName" parameterType="String" resultType="user">
select * from t_user
<where>
<if test="userName !=null and userName !=''">
name = #{userName}
</if>
</where>
</select>
将sql 改成下面的情况 在当userName 为空的情况下 sql为
select * from t_user where 显然这样desql 是无法执行的
<select id="queryUserByName" parameterType="String" resultType="user">
select * from t_user
where
<if test="userName !=null and userName !=''">
name = #{userName}
</if>
</select>
在看另外一个 当userName 为空 而 address 不为空的时候 sql 为
select * from t_user where and user_address = #{address} 这样也是不对的
使用<where> 标签就可以解决这个问题
<select id="queryUserByName" parameterType="String" resultType="user">
select * from t_user
where
<if test="userName !=null and userName !=''">
name = #{userName}
</if>
<if test="address !=null and address !=''">
and user_address = #{address}
</if>
</select>
<where> 标签 只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除
<select id="queryUserByName" parameterType="String" resultType="user">
select * from t_user
<where>
<if test="userName !=null and userName !=''">
<!-- and name = #{userName} 这里的and 或者or 会被删除-->
name = #{userName}
</if>
<if test="address !=null and address !=''">
and user_address = #{address}
</if>
</where>
</select>
1.2 choose、when、otherwise 的配合使用查询出满足不同的字段作为条件匹配的记录
有时候,我们不想使用所有的条件,而只是想从多个条件中选择一个使用
比如有传入 两个参数 name 和 address 有name 就根据name 查询
没有name 就根据address 查,如果两个都没有就查询所有
<select id="queryByChooseWhenOtherWise" resultType="user">
select * from t_user where 1 =1
<choose>
<when test="userName !=null and userName !=''">
and name = #{userName}
</when>
<when test="address != null and address !=''">
and user_address=#{address}
</when>
<otherwise>
and name ='如玉'
</otherwise>
</choose>
</select>
1.3 trim标签可以去除字符串两边的空格
<select id="getUser" resultType="User">
SELECT * FROM t_user WHERE name = #{username} AND user_address = #{address}
</select>
通过设置prefixOverrides和suffixOverrides属性,我们指定了要移除的前缀(AND、OR)和后缀(AND、OR),这样就能确保查询条件不会因为多余的空格而导致错误
<select id="getUser" resultType="User">
<trim prefixOverrides="AND | OR " suffixOverrides="AND | OR ">
SELECT * FROM user WHERE name = #{username} AND user_address = #{address}
</trim>
</select>
1.4 set 标签用于修改
<update id="updateUser">
update t_user set
<if test="username != null">name=#{username},</if>
<if test="address != null">user_address=#{address},</if>
where id=#{id}
</update>
没有使用<set> 标签 最后一列会有, 号
可以改为
<update id="updateUser">
update t_user
<set>
<if test="username != null">name=#{username},</if>
<if test="address != null">user_address=#{address},</if>
</set>
where id=#{id}
</update>
最后一列 <if test="address != null">user_address=#{address},</if> 有没有,号都可以执行
<set> 标签是帮我们去除掉最后的,号
1.5 foreach 标签在前面的章节已经使用过这里不做演示了