zoukankan      html  css  js  c++  java
  • 【MyBatis】MyBatis 动态 SQL

    MyBatis 动态SQL

    if

    可以根据实体类的不同取值,使用不同的 SQL 语句来进行查询。

    使用动态 SQL 最常见情景是根据条件包含 where 子句的一部分。

    持久层 DAO 接口:

    public interface UserDAO {
        /**
         * 根据用户信息,查询用户列表
         * @param user
         * @return
         */
        List<User> findByUser(User user);
    }
    

    DAO 映射配置:

    <mapper namespace="cn.parzulpan.dao.UserDAO">
        <select id="findByUser" resultType="User" parameterType="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>
    
    </mapper>
    

    测试:

    @Test
    public void findByUserTest() {
        User user = new User();
        user.setUsername("%Tim%");
    //        user.setAddress("%北京%");
        List<User> users = userDAO.findByUser(user);
        for (User u : users) {
            System.out.println(u);
        }
    }
    

    choose、when、otherwise

    有时候,如果不想使用所有的条件,而只是想从多个条件中选择一个使用。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。

    持久层 DAO 接口:

    public interface UserDAO {
        /***
         * 根据用户信息,查询用户列表,提供默认情况
         * @param user
         * @return
         */
        List<User> findByUserDefault(User user);
    }
    

    DAO 映射配置:

    <mapper namespace="cn.parzulpan.dao.UserDAO">
        <select id="findByUserDefault" resultType="User" parameterType="User">
            select * from user where 1 = 1
            <choose>
                <when test="username !=null and username != ''">
                    and username like #{username}
                </when>
                <when test="address != null">
                    and address like #{address}
                </when>
                <otherwise>
                    and id > 50
                </otherwise>
            </choose>
        </select>
    
    </mapper>
    

    测试:

    @Test
    public void findByUserDefaultTest() {
        User user = new User();
    //        user.setUsername("%Tim%");
        List<User> users = userDAO.findByUserDefault(user);
        for (User u : users) {
            System.out.println(u);
        }
    }
    

    trim、where、set

    为了去掉上面的 where 1 = 1 恒成立语句,可以使用 where 元素,where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。

    持久层 DAO 接口:

    public interface UserDAO {
        /**
         * 根据用户信息,查询用户列表,使用 Where
         * @param user
         * @return
         */
        List<User> findByUserWhere(User user);
    }
    

    DAO 映射配置:

    <mapper namespace="cn.parzulpan.dao.UserDAO">
        select * from user
        <where>
            <if test="username != null and username != ''">
                and username like #{username}
            </if>
            <if test="address != null">
                and address like #{address}
            </if>
        </where>
    </mapper>
    

    测试:

    @Test
        public void findByUserWhereTest() {
            User user = new User();
    //        user.setUsername("%Tim%");
            List<User> users = userDAO.findByUserWhere(user);
            for (User u : users) {
                System.out.println(u);
            }
        }
    

    也可以通过自定义 trim 元素来定制 where 元素的功能。比如,和 where 元素等价的自定义 trim 元素为:

    <trim prefix="WHERE" prefixOverrides="AND |OR ">
      ...
    </trim>
    

    prefixOverrides 属性会忽略通过管道符分隔的文本序列,上述例子会移除所有 prefixOverrides 属性中指定的内容,并且插入 prefix 属性中指定的内容。

    set 元素可以用于动态包含需要更新的列,忽略其它不更新的列,通常用于动态更新语句。

    <mapper namespace="cn.parzulpan.dao.UserDAO">
        update user
        <set>
            <if test="username != null and username != ''">
                username = #{username},
            </if>
            <if test="address != null">
                address = #{address},
            </if>
        </set>
        where id = #{id}
    </mapper>
    

    和 set 元素等价的自定义 trim 元素为:

    <trim prefix="SET" suffixOverrides=",">
      ...
    </trim>
    

    foreach

    动态 SQL 的另一个常见使用场景是对集合进行遍历,尤其是在构建 IN 条件语句的时候。

    持久层 DAO 接口:

    public interface UserDAO {
         /**
         * 根据 id 集合查询用户
         * @param v
         * @return
         */
        List<User> findByIds(QueryV v);
    }
    

    DAO 映射配置:

    <mapper namespace="cn.parzulpan.dao.UserDAO">
        <select id="findByIds" resultType="User" parameterType="QueryV">
            select * from user
            <where>
                <if test="ids != null and ids.size() > 0">
                    <foreach collection="ids" open="id in (" close=")" item="uid" separator=",">
                        #{uid}
                    </foreach>
                </if>
            </where>
        </select>
    </mapper>
    

    测试:

    @Test
    public void findByIdsTest() {
        List<Integer> ids = new ArrayList<>();
        ids.add(41);
        ids.add(42);
        ids.add(43);
        ids.add(50);
        ids.add(51);
        ids.add(60);
        QueryV queryV = new QueryV();
        queryV.setIds(ids);
        List<User> users = userDAO.findByIds(queryV);
        for (User u : users) {
            System.out.println(u);
        }
    }
    
    

    简化编写的 SQL 片段

    Sql 中可将重复的 sql 提取出来,使用时用 include 引用即可,最终达到 sql 重用的目的。

    定义代码片段:

    <!-- 抽取重复的语句代码片段 -->
    <sql id="defaultSql">
        select * from user
    </sql>
    

    引用代码片段:

    <!-- 配置查询所有操作 -->
    <select id="findAll" resultType="user">
        <include refid="defaultSql"></include>
    </select>
    
    <!-- 根据 id 查询 -->
    <select id="findById" resultType="User" parameterType="int">
        <include refid="defaultSql"></include>
        where id = #{uid}
    </select>
    

    练习和总结

  • 相关阅读:
    [翻译]关于堆和堆栈
    sql 字符+数值 混合排序 lcs
    证明DataReader分页的可行性 lcs
    谈谈我对小公司、大公司及个人成长的见解 lcs
    sina 通用js代码说明 lcs
    Linux系统下生成证书 https证书
    【转】51单片机外部中断的C51编程
    【转】如何建立个人网站
    【转】关于C51的中断编程[原创]
    【转】毫不费力:破解加密PDF文档就使用这两三招
  • 原文地址:https://www.cnblogs.com/parzulpan/p/14158145.html
Copyright © 2011-2022 走看看