动态sql
根据条件的不同, SQL 语句也会随之动态的改变. MyBatis 中,提供了一组标签用于实现动态 SQL,基于上一节的绑定接口实现CRUD。
一、if 条件判断
用于进行条件判断, test 属性用于指定判断条件. 为了拼接条件, 在 SQL 语句后强行添加 1=1 的恒成立条件.(只要有一个条件成立就会拼接到sql语句后)
- 注:不传入参数,即查询所有
<select id="selUser" resultType="Users">
select * from users where 1=1
<if test="uid!=0">
and uid = #{uid}
</if>
<if test="username!=null and username!=''">
and username = #{username}
</if>
<if test="password!=null and password!=''">
and password = #{password}
</if>
<if test="city!=null and city!=''">
and city = #{city}
</if>
</select>
接口:
public List<Users> selUser(Users users);
运行代码:
/**
* 通过传入User对象,动态比对数据库,获取值
*/
@Test
public void selUser(){
Users u = new Users();
//u.setUid(14);
//u.setUsername("张学友");
u.setCity("香港");
List<Users> users = mapper.selUser(u);
System.out.println(users);
sqlSession.close();
}
二、set 用于update更新语句
a) 满足条件时, 会自动添加 set 关键字
b) 会去除 set 子句中多余的逗号(最后一个条件可不写' , ')
c) 不满足条件时, 不会生成 set 关键字
例:update users set username=?,password=? where uid = 10;
<update id="updateUser">
update users
<set>
<if test="username!=null and username!=''">
username = #{username},
</if>
<if test="password!=null and password!=''">
password = #{password},
</if>
<if test="city!=null and city!=''">
city = #{city}
</if>
</set>
where uid = #{uid}
</update>
接口:
public int updateUser(Users users);
运行代码:
@Test
public void updateUser(){
Users users = new Users();
users.setUsername("张三");
users.setPassword("121212");
users.setUid(10);
int i = mapper.updateUser(users);
System.out.println(i);
sqlSession.commit();
sqlSession.close();
}
三、where 增加查询条件
用于管理 where 子句. 有如下功能:
a) 如果没有条件, 不会生成 where 关键字
b) 如果有条件, 会自动添加 where 关键字
c) 如果条件中有 ‘and’, 自动去除之,但不会自动加
- 注:与(一)不同的是,不需要将where条件写为1=1
- 不传入参数,即查询所有
例:select * from users WHERE username = ? and password= ?;
<select id="selUser2" resultType="Users">
select * from users
<where>
<if test="uid!=0">
and uid = #{uid}
</if>
<if test="username!=null and username!=''">
and username = #{username}
</if>
<if test="password!=null and password!=''">
and password = #{password}
</if>
<if test="city!=null and city!=''">
and city = #{city}
</if>
</where>
</select>
接口:
public List<Users> selUser2(Users users);
运行代码:
@Test
public void selUser2(){
Users u = new Users();
u.setUsername("王二");
u.setPassword("123123");
List<Users> users = mapper.selUser2(u);
System.out.println(users);
sqlSession.close();
}
四、choose...when...otherwise(了解)
单条件查询(只取其一)
这是一套标签, 功能类似于 if..elseif...elseif...else
-
注:when中取其中的一个,不会追加多个条件,如果都不满足则找otherwise中的条件查询
-
在when中,依次筛查条件,只要前面有条件满足,就不继续往后筛查
<select id="selByWhen" resultType="Users">
select * from users
<where>
<choose>
<when test="uid!=0">
uid = #{uid}
</when>
<when test="username!=null and username!=''">
username = #{username}
</when>
<when test="password!=null and password!=''">
password = #{password}
</when>
<otherwise>
city = #{city}
</otherwise>
</choose>
</where>
</select>
接口:
public List<Users> selByWhen(Users users);
运行代码:
@Test
public void selByWhen(){
Users u = new Users();
u.setUsername("李四");
u.setPassword("123");
List<Users> users = mapper.selByWhen(u);
System.out.println(users);
sqlSession.close();
}
- 上面在查询中加入了多个条件,程序按顺序筛查,username有值,且满足if条件判断,则不会去筛查password项,最终根据username进行查询
五、bind 模糊查询---相当于like
用于对数据进行再加工, 进行模糊查询
例:查询城市名包含‘京’的用户:select * from users where city like ‘%京%’;
方式一:使用bind,value中做字符串拼接:'%'+city+'%'
<select id="selLike" resultType="Users">
<bind name="c" value="'%'+city+'%'"/>
select * from users where city like #{c}
</select>
方式二:使用sql语法中的concat做拼接,concat("%",city,"%")
<select id="selLike" resultType="Users">
select * from users where city like concat("%",#{city},"%")
</select>
- 接口及运行代码:
接口:
public List<Users> selLike(Users users);
运行代码:
@Test
public void selLike(){
Users u = new Users();
u.setCity("京");
List<Users> users = mapper.selLike(u);
System.out.println(users);
sqlSession.close();
}
六、foreach 范围查询
*在一个范围中查询* 用于在 SQL 语句中遍历集合参数, 在 in 查询中使用
a) collection: 待遍历的集合 (与参数名无关)
- 如果传入的参数是List类型,collection属性值为list
- 如果传入的参数是array数组,collection属性值为array
- 如果传入的参数是Map类型,collection属性值就是传入的List或array对象在自己封装的map里面的key.
b) open: 设置开始符号
c) separator: 项目分隔符
d) close: 设置结束符号
e) item: 迭代变量
f) index:在list和数组中,index是元素的序号,在map中,index是元素的key,该参数可选。
- 以List为例:select * from users where uid in (14,16,18);
<select id="selIn" resultType="Users">
select * from users where uid in
<foreach collection="list" open="(" separator="," close=")" item="i">
#{i}
</foreach>
</select>
接口:
public List<Users> selIn(List<Integer> list);
运行代码:
@Test
public void selIn(){
List<Integer> list = new ArrayList<>();
list.add(14);
list.add(16);
list.add(18);
List<Users> users = mapper.selIn(list);
System.out.println(users);
sqlSession.close();
}
七、sql+include 动态选择要查询的具体列
<sql id="aa">
username,password
</sql>
<sql id="bb">
city
</sql>
<select id="selColumns" resultType="Users">
select
<include refid="bb"></include>
from users where uid = #{uid}
</select>
接口:
public Users selColumns(Users users);
运行代码:
@Test
public void selColumns(){
Users u = new Users();
u.setUid(9);
Users users = mapper.selColumns(u);
System.out.println(users);
sqlSession.close();
}