动态SQL
1.元素
元素 | 说明 |
---|---|
<if> | 判断语句 |
<choose>(<when>、<otherwise>) | 相当于switch...case...default |
<where>、<tirm>、<set> | 辅助元素,用于一些SQL的拼装、特殊字符问题 |
<foreach> | 循环语句,常用于in子句 |
<bind> | 创建一个变量 字符串的拼接(防注入) |
2.<if>元素
<!--<if>元素使用-->
<select id="findCustomerByNameAndJobs"
parameterType="com.itheima.po.Customer"
resultType="com.itheima.po.Customer">
select * from t_customer where 1=1
<if test="username !=null and username!=''">
and username like concat('%',#{username},'%')
</if>
<if test="jobs !=null and jobs!=''">
and jobs= #{jobs}
</if>
</select>
当test属性中的条件为true时,会输出标签中的内容 。上面配置实现了姓名和职业不是必须条件的查询。
3.<choose>、<when>、<otherwise>元素
当只需一个选项而不是一个或多个时(if)比如:当名称不为空时按照名称,职业不空时按职业,都为空时查所有
<!--<choose>(<when>、<otherwise>)元素使用-->
<select id="findCustomerByNameOrJobs"
parameterType="com.itheima.po.Customer"
resultType="com.itheima.po.Customer">
select * from t_customer where 1=1
<choose>
<when test="username !=null and username !=''">
and username like concat('%',#{username},'%')
</when>
<when test="jobs !=null and jobs !=''">
and jobs= #{jobs}
</when>
<otherwise>
and phone is not null
</otherwise>
</choose>
</select>
4.<where>、<trim>元素
where可以使我们不用加入”1=1“这样的条件,还可以自动去除多余的 ”AND“ 或 ”OR“
<select id="findCustomerByNameAndJobs"
parameterType="com.itheima.po.Customer"
resultType="com.itheima.po.Customer">
select * from t_customer
<!--使用<where>-->
<where>
<if test="username !=null and username!=''">
and username like concat('%',#{username},'%')
</if>
<if test="jobs !=null and jobs!=''">
and jobs= #{jobs}
</if>
</where>
</select>
trim也可以实现类似的行为,prefix指定语句的前缀,prefixOverrides表示需要去除的字符串
<select id="findCustomerByNameAndJobs"
parameterType="com.itheima.po.Customer"
resultType="com.itheima.po.Customer">
select * from t_customer
<!--使用<trim>-->
<trim prefix="where" prefixOverrides="and">
<if test="username !=null and username!=''">
and username like concat('%',#{username},'%')
</if>
<if test="jobs !=null and jobs!=''">
and jobs= #{jobs}
</if>
</trim>
</select>
5.<set>元素
用于在更新时只更新部分字段,提高效率 虽然可用<if>实现,但此时最后一个设置字段会有一个逗号。
这时可以用<set>来去除多余的括号
<!--<set>元素-->
<update id="updateCustomer" parameterType="com.itheima.po.Customer">
update t_customer
<set>
<if test="username !=null and username !=''">
username=#{username},
</if>
<if test="jobs !=null and jobs !=''">
jobs=#{jobs},
</if>
<if test="phone !=null and phone !=''">
phone=#{phone},
</if>
</set>
where id=#{id}
</update>
5.<foreach>元素
如果一次需要查询 100个客户信息,一次一次的查询显然不可取,我们可以使用 in 子句。
MyBatis提供了<foreach>元素
<!--<foreach>元素使用-->
<select id="findCustomerByIds" parameterType="List"
resultType="com.itheima.po.Customer">
select * from t_customer where id in
<foreach collection="list" index="index" item="id1"
open="(" separator="," close=")">
#{id1}
</foreach>
</select>
- item:从集合类型中每次取到元素的名字(要在标签中使用的)
- index:从集合类型中每次取到元素的位置下标
- collection:传递过来的类型,array、list、Map的键(如果有多个in会传Map类型)
- open 和 close:语句的开始和结束符号
- separator:每个元素的间隔符
@Test
public void findCustomerByIdsTest(){
SqlSession sqlSession = MybatisUtils.getSession();
List<Integer> ids = new ArrayList<Integer>();
ids.add(1);
ids.add(2);
List<Customer> customers = sqlSession.selectList("com.itheima.mapper"
+ ".CustomerMapper2.findCustomerByIds",ids);
for(Customer c:customers){
System.out.println(c);
}
}
6.<bind>元素
<select id="findCustomerByName" parameterType="String"
resultType="com.itheima.po.Customer">
<!--select * from t_customer where username like '%${value}%' 下方防注入-->
select * from t_customer where username like concat('%',#{value},'%')
</select>
改为
<select id="findCustomerByName" parameterType="String"
resultType="com.itheima.po.Customer">
<!--_parameter.getUsername()可以用username代替-->
<bind name="pattern_username"
value="'%'+_parameter.getUsername()+'%'" />
select * from t_customer
where username like #{pattern_username}
</select>