自学内容网 自学内容网

MyBatis(五)动态SQL

目录

一、介绍

二、if标签

三、where标签

四、choose-when-otherwise 标签

五、foreach标签

七、trim标签

 八、提取公用的SQL语句


一、介绍

        动态 SQL 是 MyBatis 的强大特性之一。在 JDBC 或其它类似的框架中,开发人员通常需要手动拼接 SQL 语句。根据不同的条件拼接 SQL 语句是一件极其痛苦的工作。例如,拼接时要确保添加了必要的空格,还要注意去掉列表最后一个列名的逗号。而动态 SQL 恰好解决了这一问题,可以根据场景动态的构建查询。

MyBatis 的动态 SQL 包括以下几种元素,如下表所示:

元素作用备注
if判断语句单条件分支判断
choose(when、otherwise)相当于 Java 中的 switch case 语句多条件分支判断
trim、where辅助元素用于处理一些SQL拼装问题
foreach循环语句在in语句等列举条件常用
bind辅助元素拼接参数

二、if标签

        MyBatis if 类似于 Java 中的 if 语句,是 MyBatis 中最常用的判断语句。使用 if 标签可以节省许多拼接 SQL 的工作,把精力集中在 XML 的维护上。

测试类

@Test
    public void testFindByWhere() throws IOException {
        // 先加载主配置文件,加载到输入流中
        InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        // 创建SqlSessionFactory对象,创建SqlSession对象
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
        // 创建SqlSession对象
        SqlSession session = factory.openSession();
​
        User user = new User();
        user.setUsername("%熊%");
        user.setSex("女");
        
        // 条件查询
        UserMapper mapper = session.getMapper(UserMapper.class);
        List<User> list = mapper.findByWhere(user);
        for (User user1 : list) {
            System.out.println(user1);
        }
        
        // 关闭资源
        session.close();
        inputStream.close();
    }

mapper接口

public interface UserMapper {
    
    // 条件查询
    public List<User> findByWhere(User user);
    
}

sql语句

    <select id="findByWhere" parameterType="com.qcbyjy.domain.User" resultType="com.qcbyjy.domain.User">
        select * from user where 1 = 1
        <if test="username != null and username != ''">
          and username like #{username}
        </if>
        <if test="sex != null and sex != ''">
            and sex = #{sex}
        </if>
    </select>

三、where标签

where标签目的就是为了去掉 where 1=1的拼接的,where标签使用在if标签的外面。

where 标签主要用来简化 SQL 语句中的条件判断,可以自动处理 AND/OR 条件。

    <!--使用where关键字-->
    <select id="findByWhere" parameterType="com.qcbyjy.domain.User" resultType="com.qcbyjy.domain.User">
        select * from user
        <where>
            <if test="username != null and username != ''">
                and username like #{username}
            </if>
            <if test="sex != null and sex != ''">
                and sex = #{sex}
            </if>
        </where>
    </select>

四、choose-when-otherwise 标签

        由于 MyBatis 并没有为 if 提供对应的 else 标签,如果想要达到<if>...<else>...</else> </if> 的效果,可以借助 <choose>、<when>、<otherwise> 来实现。

<choose>
    <when test="判断条件1">
        SQL语句1
    </when>
    <when test="判断条件2">
        SQL语句2
    </when>
    <when test="判断条件3">
        SQL语句3
    </when>
    <otherwise>
        SQL语句4
    </otherwise>
</choose>

        choose 标签按顺序判断其内部 when 标签中的判断条件是否成立,如果有一个成立,则执行相应的 SQL 语句,choose 执行结束;如果都不成立,则执行 otherwise 中的 SQL 语句。这类似于 Java 的 switch 语句,choose 为 switch,when 为 case,otherwise 则为 default。

举例:

    <select id="selectWebsite"
            parameterType="net.biancheng.po.Website"
            resultType="net.biancheng.po.Website">
        SELECT id,name,url,age,country
        FROM website WHERE 1=1
        <choose>
            <when test="name != null and name !=''">
                AND name LIKE CONCAT('%',#{name},'%')
            </when>
            <when test="url != null and url !=''">
                AND url LIKE CONCAT('%',#{url},'%')
            </when>
            <otherwise>
                AND age is not null
            </otherwise>
        </choose>
    </select>

        当网站名称不为空时,只用网站名称作为条件进行模糊查询;
        当网站名称为空,而网址不为空时,则用网址作为条件进行模糊查询;
        当网站名称和网址都为空时,则要求网站年龄不为空。

五、foreach标签

        Mybatis foreach 标签用于循环语句,它很好的支持了数据和 List、set 接口的集合,并对此提供遍历的功能。

    <!--foreach标签 select * from user where id = 1 or id = 2 or id = 3 -->
    <select id="findByIds" parameterType="com.qcbyjy.domain.User" resultType="com.qcbyjy.domain.User">
        select * from user
        <where>
            <foreach collection="ids" open="id = " separator="or id = " item="i">
                #{i}
            </foreach>
        </where>
    </select>
    <!--foreach标签 select * from user where id in (1,2,3)-->
    <select id="findByIds" parameterType="com.qcbyjy.domain.User" resultType="com.qcbyjy.domain.User">
        select * from user
        <where>
            <foreach collection="ids" open="id in ( " separator="," close=")" item="i">
                #{i}
            </foreach>
        </where>
    </select>

六、set标签

        在 Mybatis 中,update 语句可以使用 set 标签动态更新列。set 标签可以为 SQL 语句动态的添加 set 关键字,剔除追加到条件末尾多余的逗号。

    <!--使用set元素动态修改一个网站记录 -->
    <update id="updateWebsite"
            parameterType="net.biancheng.po.Website">
        UPDATE website
        <set>
            <if test="name!=null">name=#{name}</if>
            <if test="url!=null">url=#{url}</if>
        </set>
        WHERE id=#{id}
    </update>

七、trim标签

        在 MyBatis 中除了使用 if+where 实现多条件查询,还有一个更为灵活的元素 trim 能够替代之前的做法。trim 一般用于去除 SQL 语句中多余的 AND 关键字、逗号,或者给 SQL 语句前拼接 where、set 等后缀,可用于选择性插入、更新、删除或者条件查询等操作。trim 语法格式如下。

属性描述
prefix给SQL语句拼接的前缀,为 trim 包含的内容加上前缀
suffix给SQL语句拼接的后缀,为 trim 包含的内容加上后缀
prefixOverrides去除 SQL 语句前面的关键字或字符,该关键字或者字符由 prefixOverrides 属性指定。
suffixOverrides去除 SQL 语句后面的关键字或者字符,该关键字或者字符由 suffixOverrides 属性指定。
<select id="selectWebsite" resultType="net.biancheng.po.Website">
    SELECT id,name,url,age,country
    FROM website
    <trim prefix="where" prefixOverrides="and">
        <if test="name != null and name !=''">
            AND name LIKE CONCAT ('%',#{name},'%')
        </if>
        <if test="url!= null">
            AND url like concat ('%',#{url},'%')
        </if>
    </trim>
</select>
<-- SELECT id,name,url,age,country FROM website where name LIKE CONCAT ('%',?,'%') AND url like concat ('%',?,'%') -->

 八、提取公用的SQL语句

    <!--提取公共的SQL-->
    <sql id="findAllSql">
        select * from user
    </sql>
​
    <!--编写sql语句(重点练习的) com.qcbyjy.mapper.UserMapper.findAll -->
    <select id="findAll" resultType="com.qcbyjy.domain.User">
        <include refid="findAllSql" />
        /*select * from user*/
    </select>

    <!--使用where关键字-->
    <select id="findByWhere" parameterType="com.qcbyjy.domain.User" resultType="com.qcbyjy.domain.User">
        <include refid="findAllSql" />
        /*select * from user*/
        <where>
            <if test="username != null and username != ''">
                and username like #{username}
            </if>
            <if test="sex != null and sex != ''">
                and sex = #{sex}
            </if>
        </where>
    </select>

    <!--foreach标签 select * from user where id in (1,2,3)-->
    <select id="findByIds" parameterType="com.qcbyjy.domain.User" resultType="com.qcbyjy.domain.User">
        <include refid="findAllSql" />
        /*select * from user*/
        <where>
            <foreach collection="ids" open="id in ( " separator="," close=")" item="i">
                #{i}
            </foreach>
        </where>
    </select>


原文地址:https://blog.csdn.net/a13641376265/article/details/145230146

免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!