针对前面的用户信息综合查询这条sql
<!-- 用户信息综合查询 -->
<select id="findUserList" parameterType="userQueryVo" resultType="userCustom">
select * from user where user.sex = #{userCustom.sex} and user.username like '%${userCustom.username}%'
</select>
如果我们传入的参数为空,那么就会有问题。
这时就需要用到我们的if条件判断。
<!-- 用户信息综合查询 -->
<select id="findUserList" parameterType="userQueryVo" resultType="userCustom">
select * from user
<where>
<if test="userCustom != null">
<if test="userCustom.sex != null">
<!-- 第一个条件的and可以不写,写了也没关系,where标签会自动去掉第一个and -->
and user.sex = #{userCustom.sex}
</if>
<if test="userCustom.username != null">
and user.username like '%${userCustom.username}%'
</if>
</if>
</where>
</select>
测试一下:
结果跟原来一样
[User{id=10, username='张三', birthday=Wed Mar 07 08:00:00 CST 2018, sex='1', addr='成都'}, User{id=39, username='张四', birthday=Wed Mar 21 08:00:00 CST 2018, sex='1', addr='北京'}]
sql片段:
当我们的一个查询条件被多个sql公用时,这时就需要将条件进行抽取,形成单独的sql片段,方便多个sql语句来共用。
首先需要定义sql片段:
<!-- 定义sql片段
id: sql片段唯一标识
经验:是基于单标定义sql片段,这样的话sql片段可重用性才高
-->
<sql id="query_user_where">
<if test="userCustom != null">
<if test="userCustom.sex != null">
and user.sex = #{userCustom.sex}
</if>
<if test="userCustom.username != null">
and user.username like '%${userCustom.username}%'
</if>
</if>
</sql>
然后在需要的地方直接进行引用即可
<!-- 用户信息综合查询 -->
<select id="findUserList" parameterType="userQueryVo" resultType="userCustom">
select * from user
<where>
<!-- 引用定义的sql片段,如果不在本mapper中,需要加上namespace -->
<include refid="query_user_where"/>
</where>
</select>
foreach:
假设我们需要查询id为 1或10或16的用户信息。
在UserQueryVo中新添加一个属性,并生成get和set方法
在mapper.xml中添加一个foreach
<sql id="query_user_where">
<if test="userCustom != null">
<if test="userCustom.sex != null">
and user.sex = #{userCustom.sex}
</if>
<if test="userCustom.username != null">
and user.username like '%${userCustom.username}%'
</if>
<!-- 使用foreach遍历传入ids
collection:指定输入对象中集合属性
item:每个遍历生成对象
open:开始遍历时拼接的串
close:结束遍历时拼接的串
separator:遍历的两个对象中需要拼接的串
使用实现下边的sql拼接:
and (id=1 or id=10 or id=16)
-->
<foreach collection="ids" item="user_id" open="and (" close=")" separator="or">
id=#{user_id}
</foreach>
</if>
</sql>
对它进行测试
@Test
public void testfindUserList() throws Exception{
SqlSession sqlSession = factory.openSession();
//通过反射拿到UserMapper的代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
UserQueryVo userQueryVo = new UserQueryVo();
UserCustom userCustom = new UserCustom();
//查询所有性别为1并且性张的用户
userCustom.setSex("1");
userCustom.setUsername("张");
userQueryVo.setUserCustom(userCustom);
List<Integer> ids = new ArrayList<>();
ids.add(1);
ids.add(10);
ids.add(16);
userQueryVo.setIds(ids);
List user = userMapper.findUserList(userQueryVo);
System.out.println(user);
}
}
成功的输出了 性别为1,性张, 并且id 在(1,10,16)这三个数字中的用户信息
[User{id=10, username='张三', birthday=Wed Mar 07 08:00:00 CST 2018, sex='1', addr='成都'}]
上面的foreach的另外一种实现
<!-- 实现 and id in (1,10,16) 拼接 -->
<foreach collection="ids" item="user_id" open="and id in (" close=")" separator=",">
<!-- 每个遍历需要拼接的串 -->
#{user_id}
</foreach>
结果跟上面一样