1.if标签
通过if标签构建动态条件,通过其test属性的true或false来判断该添加语句是否执行。
mapper接口
public interface AccountMapper {List<Account> selectAllByCondition(Account account);
}
映射文件
<select id="selectAllByCondition" resultMap="AccountMap">select *from accountwhere 1=1<if test="id!=null and id!=''">and id=#{id}</if><if test="accountType!=null and accountType!=''">and account_type=#{accountType}</if>
</select>
这里test中的属性名与Account类中的属性名一致。例如:上述文件的第一个if标签中的id严格与Account中属性名id一致。
测试
@Test
public void sqlTest(){AccountMapper accountMapper = sqlSession.getMapper(AccountMapper.class);Account account=new Account();account.setId(1);account.setAccountType("Checking");List<Account> accounts = accountMapper.selectAllByCondition(account);System.out.println(accounts);
}
结果:
执行效果等同于select * from account where 1=1 and id=1 and account_type="Checking"
现在修改查询的id属性值,将其赋值为空,在测试类中注释掉account.setId方法
test属性是boolean类型,通过表达式判断true,false,决定此条件是否会被执行
注意其中的1=1,这样就可以解决if标签可能会带来的sql语法错误例如:
select * from account where and id=1;
当Mapper接口传递的是@Param参数指定的形参时,if标签中的test属性名应与Param参数指定的值一致
例如接口参数修改为如下形式:
public interface AccountMapper {List<Account> selectAllByCondition(@Param("AccountId") int id,@Param("accountType") String accountType);
}
映射文件应修改如下(注意AccountId的修改):
<select id="selectAllByCondition" resultMap="AccountMap">select *from accountwhere 1=1<if test="AccountId!=null and AccountId!=''">and id=#{AccountId}</if><if test="accountType!=null and accountType!=''">and account_type=#{accountType}</if>
</select>
这中映射规则与#{}值的映射类似
2.where标签
where标签是对if标签的升级版,这里用where标签替代where语句,而且它还能消除条件语句中可能出现的多余sql字段,例如and,or。
映射文件修改如下:
<select id="selectAllByCondition" resultMap="AccountMap">select *from account<where><if test="id!=null and id!=''">and id=#{id}</if><if test="accountType!=null and accountType!=''">and account_type=#{accountType}</if></where>
</select>
这里测试时id为null,此时where语句会自动去除if标签中属性值前多余的and或者or,如果and或or在属性值后面则不会生效。
3.trim标签
使用trim标签可以添加在指定sql语句前添加删除字段
映射文件修改
<select id="selectAllByCondition" resultMap="AccountMap">select *from account<trim prefix="where" prefixOverrides="and"><if test="id!=null and id!=''">and id=#{id}</if><if test="accountType!=null and accountType!=''">and account_type=#{accountType}</if></trim>
</select>
测试结果
当测试id值为null时,prefixOverrides属性值的设定取出了多余的and,prefix值的设定在trim标签前添加了where。如下,trim标签还用suffix,suffixOverrides属性,与前两个属性相对,分别是在trim标签中语句后添加值,在if标签中对and或or相对属性值后的动态处理,防止sql语句出错。
4.choose标签
如下choose标签中的when,otherwise类似与if else,它只会执行其中的一个
<select id="selectAllByCondition" resultMap="AccountMap">select *from accountwhere<choose><when test="id!=null and id!=''">id=#{id}</when><otherwise>account_type=#{accountType}</otherwise></choose>
</select>
测试方法中只设置id属性
@Testpublic void sqlTest(){AccountMapper accountMapper = sqlSession.getMapper(AccountMapper.class);Account account=new Account();account.setId(2);
// account.setAccountType("Checking");List<Account> accounts = accountMapper.selectAllByCondition(account);System.out.println(accounts);}
结果:
再将id属性设置注释掉,测试
它只会执行其中一个条件,而且一定会执行其中一个。
5.foreach标签
foreach标签是针对于集合,列表的类似与for循环
范围查询:
接口方法:
List<Account> selectByIds(@Param("ids") int [] s);
映射文件
<select id="selectByIds" resultMap="AccountMap">select * from account where id in(1,2);
</select>
测试
@Test
public void sqlTest2(){AccountMapper accountMapper = sqlSession.getMapper(AccountMapper.class);int [] ids={1,2};List<Account> accounts = accountMapper.selectByIds(ids);System.out.println(accounts);
}
修改xml,使用foreach标签
<select id="selectByIds" resultMap="AccountMap">select * from account where id in(<foreach collection="ids" item="id" separator=",">id</foreach><!--遍历ids数组,将生成的id以,隔开--> );
</select>
结果