Mybatis 动态 SQL
来源:原创 发布时间:2015-05-06 归档:mybatis
环境 :
JDK 7
Mybatis 3.2.7
Maven 3
Junit 4.11
Spring 4.1.5
Eclipse Luna
person 表
if
<select id="queryBy" parameterType="map" resultType="Person"> select * from person where sex = #{sex} <if test="address != null"> and address = #{address} </if> <if test="active != null"> and active = #{active} </if> </select>
如果没有传入 address 和 active
DEBUG [main] - ==> Preparing: select * from person where sex = ?
DEBUG [main] - ==> Parameters: 女(String)
DEBUG [main] - <== Total: 2
1 店小二 女 20 dianxiaoer@126.com 17702084228 广东茂名 false
3 店小四 女 22 dianxiaosi@yeah.net 11810011111 广东广州 true
DEBUG [main] - ==> Parameters: 女(String)
DEBUG [main] - <== Total: 2
1 店小二 女 20 dianxiaoer@126.com 17702084228 广东茂名 false
3 店小四 女 22 dianxiaosi@yeah.net 11810011111 广东广州 true
如果同时传入 address 和 active
DEBUG [main] - ==> Preparing: select * from person where sex = ? and address = ? and active = ?
DEBUG [main] - ==> Parameters: 女(String), 广东茂名(String), false(Boolean)
DEBUG [main] - <== Total: 1
1 店小二 女 20 dianxiaoer@126.com 17702084228 广东茂名 false
DEBUG [main] - ==> Parameters: 女(String), 广东茂名(String), false(Boolean)
DEBUG [main] - <== Total: 1
1 店小二 女 20 dianxiaoer@126.com 17702084228 广东茂名 false
如果传入 address 和 active 其中的一个 ( 如 address )
DEBUG [main] - ==> Preparing: select * from person where sex = ? and address = ?
DEBUG [main] - ==> Parameters: 女(String), 广东茂名(String)
DEBUG [main] - <== Total: 1
1 店小二 女 20 dianxiaoer@126.com 17702084228 广东茂名 false
DEBUG [main] - ==> Parameters: 女(String), 广东茂名(String)
DEBUG [main] - <== Total: 1
1 店小二 女 20 dianxiaoer@126.com 17702084228 广东茂名 false
可以知道, <if> 实现的是 if 逻辑。凡是符合条件的语句都会被执行。但 <if> 不能实现 if/else 的逻辑。
choose-when-otherwise
<select id="findBy" parameterType="map" resultType="Person"> select * from person where age > #{age} <choose> <when test="sex != null"> and sex = #{sex} </when> <when test="address != null"> and address = #{address} </when> <otherwise> and active = true </otherwise> </choose> </select>
如果没有传入 sex 和 address
DEBUG [main] - ==> Preparing: select * from person where age > ? and active = true
DEBUG [main] - ==> Parameters: 18(Integer)
DEBUG [main] - <== Total: 2
2 店小三 男 21 dianxiaosan@163.com 13800138000 广东茂名 true
3 店小四 女 22 dianxiaosi@yeah.net 11810011111 广东广州 true
DEBUG [main] - ==> Parameters: 18(Integer)
DEBUG [main] - <== Total: 2
2 店小三 男 21 dianxiaosan@163.com 13800138000 广东茂名 true
3 店小四 女 22 dianxiaosi@yeah.net 11810011111 广东广州 true
如果同时传入 sex 和 address
DEBUG [main] - ==> Preparing: select * from person where age > ? and sex = ?
DEBUG [main] - ==> Parameters: 18(Integer), 女(String)
DEBUG [main] - <== Total: 2
1 店小二 女 20 dianxiaoer@126.com 17702084228 广东茂名 false
3 店小四 女 22 dianxiaosi@yeah.net 11810011111 广东广州 true
DEBUG [main] - ==> Parameters: 18(Integer), 女(String)
DEBUG [main] - <== Total: 2
1 店小二 女 20 dianxiaoer@126.com 17702084228 广东茂名 false
3 店小四 女 22 dianxiaosi@yeah.net 11810011111 广东广州 true
如果传入 sex 和 address 其中的一个 ( 如 address )
DEBUG [main] - ==> Preparing: select * from person where age > ? and address = ?
DEBUG [main] - ==> Parameters: 18(Integer), 广东茂名(String)
DEBUG [main] - <== Total: 2
1 店小二 女 20 dianxiaoer@126.com 17702084228 广东茂名 false
2 店小三 男 21 dianxiaosan@163.com 13800138000 广东茂名 true
DEBUG [main] - ==> Parameters: 18(Integer), 广东茂名(String)
DEBUG [main] - <== Total: 2
1 店小二 女 20 dianxiaoer@126.com 17702084228 广东茂名 false
2 店小三 男 21 dianxiaosan@163.com 13800138000 广东茂名 true
choose-when-otherwise 实现的是 if、else if、else 的逻辑。
where
<select id="selectBy" parameterType="map" resultType="Person"> select * from person <where> <if test="id != null"> id = #{id} </if> <if test="age != null"> and age = #{age} </if> <if test="sex != null"> and sex = #{sex} </if> <if test="name != null"> and name = #{name} </if> <if test="email != null"> and email = #{email} </if> <if test="phone != null"> and phone = #{phone} </if> <if test="address != null"> and address = #{address} </if> <if test="active != null"> and active = #{active} </if> </where> </select>
如果不传任何参数
DEBUG [main] - ==> Preparing: select * from person
DEBUG [main] - ==> Parameters:
DEBUG [main] - <== Total: 3
1 店小二 女 20 dianxiaoer@126.com 17702084228 广东茂名 false
2 店小三 男 21 dianxiaosan@163.com 13800138000 广东茂名 true
3 店小四 女 22 dianxiaosi@yeah.net 11810011111 广东广州 true
DEBUG [main] - ==> Parameters:
DEBUG [main] - <== Total: 3
1 店小二 女 20 dianxiaoer@126.com 17702084228 广东茂名 false
2 店小三 男 21 dianxiaosan@163.com 13800138000 广东茂名 true
3 店小四 女 22 dianxiaosi@yeah.net 11810011111 广东广州 true
如果仅传 id 参数
DEBUG [main] - ==> Preparing: select * from person WHERE id = ?
DEBUG [main] - ==> Parameters: 1(Integer)
DEBUG [main] - <== Total: 1
1 店小二 女 20 dianxiaoer@126.com 17702084228 广东茂名 false
如果传非 id 参数
DEBUG [main] - ==> Parameters: 1(Integer)
DEBUG [main] - <== Total: 1
1 店小二 女 20 dianxiaoer@126.com 17702084228 广东茂名 false
DEBUG [main] - ==> Preparing: select * from person WHERE active = ?
DEBUG [main] - ==> Parameters: true(Boolean)
DEBUG [main] - <== Total: 2
2 店小三 男 21 dianxiaosan@163.com 13800138000 广东茂名 true
3 店小四 女 22 dianxiaosi@yeah.net 11810011111 广东广州 true
DEBUG [main] - ==> Parameters: true(Boolean)
DEBUG [main] - <== Total: 2
2 店小三 男 21 dianxiaosan@163.com 13800138000 广东茂名 true
3 店小四 女 22 dianxiaosi@yeah.net 11810011111 广东广州 true
可以看到, 只有在一个或以上满足 if 条件的时候, where 子句才会被插入, 并且, <where> 会自动的正确的去掉 where 子句中多余的 and 或 or 条件。
你还可以这样做 :
你还可以这样做 :
<sql id="sqlWhere"> <where> <if test="id != null"> id = #{id} </if> <if test="age != null"> and age = #{age} </if> <if test="sex != null"> and sex = #{sex} </if> <if test="name != null"> and name = #{name} </if> <if test="email != null"> and email = #{email} </if> <if test="phone != null"> and phone = #{phone} </if> <if test="address != null"> and address = #{address} </if> <if test="active != null"> and active = #{active} </if> </where> </sql> <select id="selectBy" parameterType="map" resultType="Person"> select * from person <include refid="sqlWhere" /> </select>
将 where 单独抽出来, 这样可以达到重用的目的, 在需要使用的地方, 用 <include> 引进来即可。
set
<update id="update" parameterType="Person"> update person <set> <if test="age != null"> age = #{age}, </if> <if test="sex != null"> sex = #{sex}, </if> <if test="name != null"> name = #{name}, </if> <if test="email != null"> email = #{email}, </if> <if test="phone != null"> phone = #{phone}, </if> <if test="address != null"> address = #{address}, </if> <if test="active != null"> active = #{active} </if> </set> where id = #{id} </update>
与 <where> 相类似, <set> 可以自动的正确的清除 set 子句中无关的 "," 号。当然, 你也可以像 <where> 那样, 将它单独抽出来 :
<sql id="sqlSet"> <set> <if test="age != null"> age = #{age}, </if> <if test="sex != null"> sex = #{sex}, </if> <if test="name != null"> name = #{name}, </if> <if test="email != null"> email = #{email}, </if> <if test="phone != null"> phone = #{phone}, </if> <if test="address != null"> address = #{address}, </if> <if test="active != null"> active = #{active} </if> </set> </sql> <update id="update" parameterType="Person"> update person <include refid="sqlSet" /> where id = #{id} </update>
这样可以达到重用 sql 子句的目的。
foreach
<select id="search" parameterType="list" resultType="Person"> select * from person where id in <foreach collection="list" item="item" open="(" separator="," close=")"> #{item} </foreach> </select>
<foreach> 用于遍历一个集合。collection 为传进来的集合参数, item 定义迭代的变量的名称, open 和 close 定义开闭的字符, separator 定义迭代之间的分隔符。若传进参数 [1, 2]
DEBUG [main] - ==> Preparing: select * from person where id in ( ? , ? )
DEBUG [main] - ==> Parameters: 1(Integer), 2(Integer)
DEBUG [main] - <== Total: 2
1 店小二 女 20 dianxiaoer@126.com 17702084228 广东茂名 false
2 店小三 男 21 dianxiaosan@163.com 13800138000 广东茂名 true
DEBUG [main] - ==> Parameters: 1(Integer), 2(Integer)
DEBUG [main] - <== Total: 2
1 店小二 女 20 dianxiaoer@126.com 17702084228 广东茂名 false
2 店小三 男 21 dianxiaosan@163.com 13800138000 广东茂名 true