很多时候查询/修改会根据不同数据执行不同的sql语句,一般情况下,我们需要对sql进行拼装。在MyBatis中可以通过动态SQL实现,就避免了拼装SQL
if语句:满足条件,则执行语句
choose when 条件一,when 条件二......otherwise相当于if()else if()...else(),如果when的条件不满足,则会执行otherwise代码块中的SQL语句。
值得注意的是下面的例子中有两个id为selectIf的查询,两个传递的参数不同,一个是基础数据类型,一个是类对象。传参为基础数据类型,那么在判断、#后面传递参数的时候使用_parameter;传参为类对象,则使用类中对应的属性
<select id="selectIf" parameterType="int" resultType="Student"> select * from student where 1=1 <if test="_parameter != null"> and studentId=#{_parameter} </if> </select> <select id="selectIf" parameterType="Student" resultType="Student"> select * from student where 1=1 <if test="studentId != null and studentId != 0"> and studentId=#{studentId} </if> </select> <select id="selectChoose" resultType="Student" parameterType="Student"> select * from student where 1=1 <choose> <when test="studentId != null and studentId != 0"> and studentId=#{studentId} </when> <otherwise> and name=#{name} </otherwise> </choose> </select>
以上代码,每次使用条件时都添加了1=1,这样其实是不正确的,但我们需要条件,所以where和set就出来了。where用于删除没必要的and(在执行第一个条件时,是不需要and的),set用于update,在修改字段值时,没个字段后面都有一个“,”但是最后一个后面不应该有“,”而set便用于去除最后一个逗号
trim即格式化SQL代码,trim有四个属性,这四个属性都配套使用
- prefix:前缀增加
- suffix:后缀增加
- prefixOverrides:自动判断前置
- suffixOverrides:自动判断后置
<select id="selectIfWhere" resultType="Student" parameterType="Student"> select * from student <where> <if test="studentId != null and studentId != 0"> and studentId=#{studentId} </if> <if test="name != null and studentId != ''"> and name=#{name} </if> <if test="zhuangtai != null and zhuangtai != 0"> and zhuangtai=#{zhuangtai} </if> </where> </select> <update id="updateSet" parameterType="Student"> update student <set> <if test="name != null and name != ''"> name=#{name}, </if> <if test="zhuangtai != null"> zhuangtai=#{zhuangtai}, </if> </set> </update> <select id="selectTrim" parameterType="Student" resultType="Student"> select * from student <trim prefix="where" prefixOverrides="and|or"> <if test="studentId != null and studentId != 0"> and studentId=#{studentId} </if> <if test="name != null and studentId != ''"> and name=#{name} </if> <if test="zhuangtai != null and zhuangtai != 0"> and zhuangtai=#{zhuangtai} </if> </trim> </select>
foreach
foreach 语句为数组或对象集合中的每个元素重复一个嵌入语句组。foreach 语句用于循环访问集合以获取所需信息
基础数据类型的list:where标记之后输出的sql语句WHERE id in ( ? , ? )
<select id="selectForeach" resultType="JikeUser" parameterType="list"> select * from jikeUser <where> id in <foreach collection="list" index="index" item="item" open="(" separator="," close=")"> #{item} </foreach> </where> </select>
@Test
List<Integer> selectList = new ArrayList<>(); selectList.add(1); selectList.add(2); List<JikeUser> jikeUsers = sqlSession.selectList("selectForeach",selectList); for(JikeUser jikeUser : jikeUsers) System.out.println(jikeUser.getUserName());
类对象的list:where标记之后输出的sql语句WHERE (username like ? and password = ?) or (username like ? and password = ?)
<select id="selectForeach1" resultType="JikeUser" parameterType="list"> select * from jikeUser <where> <foreach collection="list" index="index" item="item" open="" separator="or" close=""> (username like #{item.userName} and password = #{item.password}) </foreach> </where> </select>
@Test
List<JikeUser> selectList = new ArrayList<>(); selectList.add(new JikeUser("jike00100", "666666")); selectList.add(new JikeUser("author001", "123456")); List<JikeUser> jikeUsers = sqlSession.selectList("selectForeach1",selectList); for(JikeUser jikeUser : jikeUsers) System.out.println(jikeUser.getUserName());
数组:where标记之后输出的sql语句WHERE id in ( ? , ? )
<select id="selectForeach" resultType="JikeUser" parameterType="java.util.ArrayList"> select * from jikeUser <where> id in <foreach collection="array" index="index" item="item" open="(" separator="," close=")"> #{item} </foreach> </where> </select>
@Test
int[] selectList = {1,2}; List<JikeUser> jikeUsers = sqlSession.selectList("selectForeach",selectList); for(JikeUser jikeUser : jikeUsers) { System.out.println(jikeUser.getUserName());
HashMap:where标记之后输出的sql语句WHERE userName like "%"?"%" and id in ( ? , ? )
<!-- #{name}中的name为HashMap中的键;collection="ids"中ids为HashMap中的键 -->
<select id="selectForeach2" resultType="JikeUser" parameterType="java.util.HashMap"> select * from jikeUser <where> userName like "%"#{name}"%" and id in <foreach collection="ids" index="index" item="item" open="(" separator="," close=")"> #{item} </foreach> </where> </select>
@Test
List<Integer> ids = new ArrayList<>(); ids.add(1); ids.add(2); HashMap<String, Object> hashMap = new HashMap<>(); hashMap.put("ids", ids); hashMap.put("name", "jike00100"); List<JikeUser> jikeUsers = sqlSession.selectList("selectForeach2",hashMap); for(JikeUser jikeUser : jikeUsers) System.out.println(jikeUser.getUserName());
由以上例子可以得出foreach中collection的参数一定是集合或数组等