动态 SQL 之<if>标签
我们根据实体类的不同取值,使用不同的 SQL 语句来进行查询。比如在 id 如果不为空时可以根据 id 查询, 如果 username 不同空时还要加入用户名作为条件。这种情况在我们的多条件组合查询中经常会碰到。
1.1 持久层 Dao 接口
public interface IUserDao { /** * 根据用户信息,查询用户列表 */ List<User> findByUser(User user); }
1.2 持久层 Dao 映射配置
<!--根据user信息查询用户列表--> <select id="findByUser" parameterType="User" resultType="User"> select * from user where 1=1 <if test="userName != null and userName != ''"> and username like #{userName} </if> <if test="address != null"> and address like #{address} </if> </select>
注意:1. <if>标签的使用:如果传入的参数对象里的某个属性满足<if>标签中的test内容,则把该标签下的sql语句添加到主语句中,以此类推,如遇到不满足的就跳过。
2. <if>标签的 test 属性中写的是对象的属性名,如果是包装类的对象要使用 OGNL 表达式的写法。 另外要注意 where 1=1 的作用~!
1.3 测试
@Test public void testFindByUser(){ User user = new User(); user.setUserName("%王%"); user.setAddress("%北京%"); List<User> users = userDao.findByUser(user); for (User u:users){ System.out.println(u); } }
动态 SQL 之<where>标签
为了简化上面 where 1=1 的条件拼装,我们可以采用<where>标签来简化开发。同时我们也可以可将重复的 sql语句提取出来,使用时用 include 引用即可,最终达到 sql 重用的目的。
2.1 持久层 Dao 映射配置
<mapper namespace="com.churujianghudezai.dao.IUserDao"> <!-- 抽取重复的语句代码片段 --> <sql id="defaultSql">select * from user </sql> <!--根据user信息查询用户列表--> <select id="findByUser" parameterType="User" resultType="User"> /*select * from user*/ <include refid="defaultSql"></include> <where> <if test="userName != null and userName != ''"> and username like #{userName} </if> <if test="address != null"> and address like #{address} </if> </where> </select> </mapper>
动态标签之<foreach>标签
3.1 需求
传入多个 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)
这样我们在进行范围查询时,就要将一个集合中的值,作为参数动态添加进来。 这样我们将如何进行参数的传递?
3.1.1 在 QueryVo 中加入一个 List 集合用于封装参数
public class QueryVo implements Serializable { private List<Integer> ids; public List<Integer> getIds() { return ids; } public void setIds(List<Integer> ids) { this.ids = ids; } }
3.2 持久层 Dao 接口
/** * 根据对象vo中的id 集合查询用户 */ List<User> findInIds(QueryVo vo);
3.3 持久层 Dao 映射配置
<!-- 抽取重复的语句代码片段 --> <sql id="defaultSql"> select * from user </sql> <!--根据 ids 集合查询用户 --> <select id="findInIds" parameterType="QueryVo" resultType="User"> <include refid="defaultSql"></include> <where> <if test="ids != null and ids.size()>0"> <foreach collection="ids" open="id in (" close=")" item="id" separator=","> #{id} </foreach> </if> </where> </select>
SQL 语句: select 字段 from user where id in (?)
<foreach>标签用于遍历集合,它的属性:
collection:代表要遍历的集合元素,注意编写时不要写#{}
open:代表语句的开始部分
close:代表结束部分
item:代表遍历集合的每个元素,生成的变量名
sperator:代表分隔符
3.3.1 编写测试方法
@Test public void testFindInIds(){ QueryVo vo = new QueryVo(); List<Integer> ids = new ArrayList<Integer>(); ids.add(50); ids.add(52); ids.add(59); vo.setIds(ids); List<User> us = userDao.findInIds(vo); for(User u: us){ System.out.println(u); } }
3.3.2 测试结果