传统的使用JDBC的方法,在组合复杂的的SQL语句的时候,需要去拼接,稍不注意哪怕少了个空格,都会导致错误。Mybatis的动态SQL功能为了解决这种问题, 通过 if, choose, when, otherwise, trim, where, set, foreach标签,可组合成非常灵活的SQL语句,从而提高开发人员的效率
实体类entity
User.java
public class User {
private String id;
private String username;
private String password;
private String sex;
private String address;
/*无参构造,有参构造,get/set方法,toString方法*/
}
数据库
表结构
user表
1.if标签
假设查询的时候并不需要列出所有的条件,而只是从多个可选条件中选择一个或者多个进行查询,使用if
标签实现
<select id="selectUserIf" parameterType="User" resultType="User">
<!-- select * from user where 1=1 -->
<!-- where 1=1 也可以写成<where></where>标签 -->
select * from user
<where>
<if test="id!=null">
and id = #{id}
</if>
<if test="sex!=null">
and sex=#{sex}
</if>
<if test="username!=null">
and username = #{username}
</if>
<if test="password!= null">
and password = #{password}
</if>
<if test="address!= null">
and address=#{address}
</if>
</where>
</select>
Tips:在if
标签中,只要test
中的表达式为true
,就会执行if
标签中的条件,即在sql
语句中使用一个或多个and
条件来进行拼接完成查询
例:查询user表中性别为“男”,地址为“西安”的用户
// 读取配置文件
InputStream in = new FileInputStream("src/main/resources/mybatis.xml");
// 解析配置文件
SqlSessionFactory sf = new SqlSessionFactoryBuilder().build(in);
//打开session
SqlSession session = sf.openSession();
User u = new User();
u.setSex("男");
u.setAddress("西安");
List<User> list = session.selectList("Users.selectUserIf",u);
for (User user : list) {
System.out.println(user);
}
//提交
session.commit();
//关闭
session.close();
2.choose标签
choose标签功能与switch语句相似,choose即switch,when对应case,otherwise对应default;
choose标签是按顺序判断其内部when标签中的test条件出否成立,如果有一个成立,则 choose 结束。当 choose 中所有 when 的条件都不满则时,则执行 otherwise 中的sql
<select id="selectUserChoose" parameterType="User" resultType="User">
<!-- 1=1 是恒成立的,where默认为1=1,即使不选择任何条件,sql查询也不会出错 -->
select * from user where 1=1
<choose>
<when test="id!=null">
and id=#{id}
</when>
<when test="username!=null">
and username=#{username}
</when>
<otherwise>
and sex=#{sex}
</otherwise>
</choose>
</select>
上面mapper映射中的select表示的是:
- 如果参数
User
的id
不为空就按照id
查询; - 如果
id
为null
,就按照username
查询; - 如果
id
和username
都为null
,就按照sex
查询
User u = new User();
//u.setId("1");
u.setUsername("王五");
u.setSex("男");
List<User> list = session.selectList("Users.selectUserChoose",u);
for (User user : list) {
System.out.println(user);
}
//提交
session.commit();
//关闭
session.close();
Tips:if
标签是与(and)的关系,而choose
标签是或(or)的关系
3.foreach标签
foreach标签顾名思义是用来实现遍历操作的,遍历对象可以是集合,也可以是数组。
foreach标签相关属性:
- collection 表示集合类型,比如list,map,array
- index表示索引
- separator表示分隔符,即迭代时每个元素之间以什么分隔
- item表示每次循环的对象,即在迭代过程中每一个元素的别名
- open表示拼接开始字符
- close表示拼接结束字符
例:每次添加多个User对象,且只添加id
和username
属性
<insert id="insertUsersForeach">
insert into user(id,username) values
<foreach collection="list" index="n" separator="," item="u">
<!-- foreach 循环 -->
<!-- collection 集合类型,比如list,map,array -->
<!-- index 索引 -->
<!-- separator 分隔符 -->
<!-- item 每次循环的项,即传递过来的对象 -->
<!-- open 拼接开始字符 -->
<!-- close 拼接结束字符 -->
(#{u.id},#{u.username})
</foreach>
</insert>
User u1 = new User();
u1.setId("5");
u1.setUsername("小明");
User u2 = new User();
u2.setId("9");
u2.setUsername("小红");
List<User> users = new ArrayList<User>();
users.add(u1);
users.add(u2);
session.insert("Users.insertUsersForeach", users);
//提交
session.commit();
//关闭
session.close();
例:查询地址为“西安”,“长春”的用户
<select id="selectUserByAddress" resultType="User">
select * from user where address in
<foreach collection="list" item="item" separator="," open="(" close=")">
#{item}
</foreach>
</select>
拼接后的sql语句
List<String> address = new ArrayList<String>();
address.add("西安");
address.add("长春");
List<User> list = session.selectList("Users.selectUserByAddress",address);
for (User user : list) {
System.out.println(user);
}
//提交
session.commit();
//关闭
session.close();
例:查询username中带有“张”字(有是可能姓“张”,也有可能名字中带有“张”),且地址为“西安”或“北京”的用户
Tips:当使用模糊查询需要拼接字符串的时候,就不能单纯传递一个List
,可以考虑将需要传递的字符串和List
放入Map
中进行传递
<select id="selectUsersByAddressAndUsername" resultType="User">
<!-- sql语句使用通配符时,需要加" ",否则会报错-->
SELECT
*
FROM
USER
WHERE
username LIKE "%"#{str.username}"%"
AND address IN
<foreach collection="city" item="item" separator="," open="(" close=")">
#{item}
</foreach>
</select>
拼接的后sql语句
List<String> address = new ArrayList<String>();
address.add("西安");
address.add("北京");
User u = new User();
u.setUsername("张");
Map<String, Object> map = new HashMap<String, Object>();
//将User放进Map中
map.put("str", u);
//将List放进Map中
map.put("city", address);
//传递Map使用selectList即可
List<User> list = session.selectList("Users.selectUsersByAddressAndUsername", map);
for (User user : list) {
System.out.println(user);
}
//提交
session.commit();
//关闭
session.close();