【MyBatis】Mybatis 的动态 SQL 语句if,where,foreach,代码片段的定义与引用
1. if
我们根据实体类的不同取值,使用不同的 SQL 语句来进行查询。比如在 id 如果不为空时可以根据 id 查询,如果 username 不同空时还要加入用户名作为条件。这种情况在我们的多条件组合查询中经常会碰到。
所以我们可以使用if标签以及test属性:
持久层DAO映射配置findUserByCondition:
<!-- 根据条件查询 -->
<select id="findUserByCondition" resultType="com.siyi.domain.User" parameterType="com.siyi.domain.User">
select * from user where 1=1
<if test="username != null">
and username = #{username}
</if>
<if test="sex != null">
and sex=#{sex}
</if>
</select>
注意: 标签的 test 属性中写的是对象的属性名,如果是包装类的对象要使用 OGNL 表达式的写法。
另外要注意 where 1=1 的作用~!
2. where
为了简化上面 where 1=1 的条件拼装,我们可以采用标签来简化开发。
持久层 Dao 映射配置findUserByCondition:
<!-- 根据条件查询 -->
<select id="findUserByCondition" resultType="com.siyi.domain.User" parameterType="com.siyi.domain.User">
select * from user
<where>
<if test="username != null">
and username = #{username}
</if>
<if test="sex != null">
and sex=#{sex}
</if>
</where>
</select>
3. foreach
传入多个 id 查询用户信息,用下边两个 sql 实现:
SELECT * FROM USERS WHERE username LIKE '%张%' AND (id =10 OR id =89 OR id=16)
SELECT * FROM USERS WHERE username LIKE '%张%' AND id IN (10,89,16)
这样我们在进行范围查询时,就要将一个集合中的值,作为参数动态添加进来。
这样我们将如何进行参数的传递?
那么首先我们传递参数必须包含这些id;
所以我们可以在参数对象中添加一个list集合。
在 QueryVo 中加入一个 List 集合用于封装参数
扫描二维码关注公众号,回复:
9963581 查看本文章
public class QueryVo implements Serializable {
private List<Integer> ids;
public List<Integer> getIds() {
return ids;
}
public void setIds(List<Integer> ids) {
this.ids = ids;
}
}
持久层 Dao 接口:
package com.siyi.dao;
import com.siyi.domain.QueryVo;
import com.siyi.domain.User;
import java.util.List;
/**
* 用户持久层接口
*/
public interface IUSerDao {
/**
* 根据queryVo中id集合查询
* @param vo
* @return
*/
public List<User> findInIds(QueryVo vo);
}
持久层 Dao 映射配置;
<!-- 根据queryvo中的id集合实现查询用户列表 -->
<select id="findInIds" resultType="com.siyi.domain.User" parameterType="com.siyi.domain.QueryVo">
select * from user
<where>
<if test="ids != null and ids.size()>0">
<foreach collection="ids" open="and id in (" close=")" item="id" separator=",">
#{id}
</foreach>
</if>
</where>
</select>
SQL 语句:
select 字段 from user where id in (?)
<foreach>
标签用于遍历集合,它的属性:
collection
:代表要遍历的集合元素,注意编写时不要写#{}
open
:代表语句的开始部分
close
:代表结束部分
item
:代表遍历集合的每个元素,生成的变量名
sperator
:代表分隔符
4. 代码片段的定义与引用
Sql 中可将重复的 sql 提取出来,使用时用 include 引用即可,最终达到 sql 重用的目的。
<!-- 抽取重复的sql语句 -->
<sql id="defaultUser">
select * from user
</sql>
<!-- 查询所有 -->
<select id="findAll" resultType="com.siyi.domain.User">
<!-- select * from user; -->
<include refid="defaultUser"></include>
</select>
<!-- 根据queryvo中的id集合实现查询用户列表 -->
<select id="findInIds" resultType="com.siyi.domain.User" parameterType="com.siyi.domain.QueryVo">
<!-- select * from user -->
<include refid="defaultUser"></include>
<where>
<if test="ids != null and ids.size()>0">
<foreach collection="ids" open="and id in (" close=")" item="id" separator=",">
#{id}
</foreach>
</if>
</where>
</select>