在我们传统JDBC中查询数据,有时候需要一个条件,有时候需要两个条件,也有时候并不需要条件,因此我们不仅要注意sql的拼接错误,还要注意多个条件之间的and和or的连接,这些事情对于我们来说都是非常痛苦的。mybatis给我们提供了动态sql,这个强大的特性帮我们解决了上面恼人的问题。
1、动态sql都有哪些?
动态sql是基于OGNL的表达式来完成的动态sql。常见的动态sql元素包括:
- if
- choose(when、otherwise)
- where
- set
- foreach
2、if标签怎么使用?
现有页面需要输入用户的name和用户的address,其中name是必须输入的,address可以选择性输入,我们的映射文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mybatis.mapper.UserMapper">
<select id="findUser" resultType="User" parameterType="User">
SELECT * FROM user where name = #{name}
<!-- 如果address不为空,才会执行此标签内的sql,否则忽略 -->
<if test="address != null">
and address = #{address}
</if>
</select>
</mapper>
3、choose、when、otherwise标签怎么使用?
现有页面,有一个文本框,可以输入id,也可以输入address,如果输入的是id,则查找所有id符合输入的用户,如果输入address,则查找所有address符合输入的用户,如果输入的不是id也不是address,则查找name为“caixiaobai”的所有用户,我们的映射文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mybatis.mapper.UserMapper">
<select id="findUser" resultType="User" parameterType="User">
SELECT * FROM user where
<choose>
<when test="id != null">
id = #{id}
</when>
<when test="address != null">
address = #{address}
</when>
<otherwise>
name = 'caixiaobai'
</otherwise>
</choose>
</select>
</mapper>
4、where标签怎么使用?
第3问中,我们解决了问题,但是如果我们并不需要otherwise中的条件该怎么办呢?如果直接去掉,那上面两个when都不满足的时候这个sql就成了SELECT * FROM user where
,显然这个sql是错误的。我们可以使用where的动态sql来解决这个问题。映射文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mybatis.mapper.UserMapper">
<select id="findUser" resultType="User" parameterType="User">
SELECT * FROM user
<where>
<if test="id != null">
id = #{id}
</if>
<if test="address != null">
address = #{address}
</if>
</where>
</select>
</mapper>
5、set标签怎么使用?
先有页面,具有文本框name、age、address、orderid,这些文本框都是选择性输入的,提交之后在数据库更新一条数据,由于这些文本框都可以选择性输入,所以添加的时候用一条普通的sql无法做到,使用动态sql可以做到,映射文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mybatis.mapper.UserMapper">
<update id="updateUser" parameterType="User">
UPDATE user
<set>
<if test="name != null">name = #{name},</if>
<if test="age != 0">age = #{age},</if>
<if test="address != null">address = #{address},</if>
<if test="orderid != 0">orderid = #{orderid}</if>
</set>
WHERE id = #{id};
</update>
</mapper>
6、foreach标签怎么使用?
我们上节课讲到传参可以使简单类型、自定义类型、map集合,还可以是list、set集合,list、set集合主要是使用在带in关键字的sql,比如SELECT * FROM user WHERE id IN(1,2,3,4,5)
,在动态sql中就是使用foreach标签来遍历传参进来的list或者set,我们看一下映射文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mybatis.mapper.UserMapper">
<select id="findUser" parameterType="ArrayList" resultType="User">
SELECT * FROM user WHERE id IN
<!-- open属性会指定遍历前的前缀,close属性会指定遍历后的后缀,separator会指定元素之间添加的字符串 -->
<foreach collection="list" item="id" index="index" open="(" close=")" separator=",">
#{id}
</foreach>
</select>
</mapper>