针对前面的用户信息综合查询这条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>结果跟上面一样