MyBatis动态SQL

动态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>
上一篇:HTML URL 编码参考手册


下一篇:hibernate使用外键查询