mybatis学习——动态SQL

动态 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 测试结果

原文地址:https://www.cnblogs.com/churujianghudezai/p/12245984.html