Mybatis入门,day2,动态SQL

发布于:2024-04-26 ⋅ 阅读:(22) ⋅ 点赞:(0)

Mybatis入门,day2,动态SQL



前言

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


一、为什么要实现动态SQL

动态 SQL 大大减少了编写代码的工作量,更体现了 MyBatis 的灵活性、高度可配置性和可维护性。

二、使用步骤

1.where和if

与之前一样,在接口中添加新的方法,加入新的方法findUserByCondition方法,参数是user对象,返回值为user列表。

public List<User> findUserByCondition(User user);

mapping映射文件中补充相应的方法。

如下图所示的mapping映射文件中添加了以下标签

where标签,当where标签中的条件出现成立时,where标签会在变成SQL语句时自动变为SQL关键字,而当标签中条件都不成立时,则自动消失。同时where后如果紧跟出现and,则会把and消除。

if标签,if标签中的test是if的判断条件如果test中的条件成立,则会在where关键字后面添加if标签中间的语句。test中的id或password是参数User中的属性。,当有多个if标签的test条件都成立时,则if标签中的内容都会拼接到where后。

    <select id="findUserByCondition" parameterType="User" resultType="User">
        select * from test
        <where>
            <if test="id !=null">
                and id = #{id}
            </if>
            <if test="password != null">
                and password = #{password}
            </if>
        </where>
    </select>

通过这些动态的查询拼接语句,可以根据传进来的条件,动态的查询某一项数据。

2.set和if

在SQL语句中更新和select查询语句类似,语句中的set标签与select中的where标签功能相似,如果set标签中的某些保留,则set标签会变为SQL语句的set关键字,并将if中test成立的标签中的内容加入到set后面。

if标签和1中的if标签功能一样,这里就不再过多赘述。

public int updateUserByCondition(User user);
<update id="updateUserByCondition" parameterType="User">
        update test
        <set>
            <if test="username != null">
                username = #{username}
            </if>

            <if test="password!=null">
                password = #{password}
            </if>
        </set>
        where id = #{id}
    </update>

3.foreach方法

foreach方法实现的是类似与SQL中的where id in(1,2,3)的语句,不过采用了where id = 1 or id =2 or id = 3的模式。

一样是在mapper文件中编写接口,并在映射文件中编写映射。

在foreach方法中我们采用迭代方式,传入的参数实际上是上方where id in(1,2,3)中括号中的数据。我们将这些数据以列表的方式传入。

而在映射文件中,我们在原有的where标签中加入新的foreach标签,在foreach标签中,collection后面加的是传入的类型,必须是可迭代类型,item是用id表示列表迭代过程中的参数名,每循环一次,id就等于不同的值。

open和colse以及separator分别是下方内容的一些属性添加
这里的open和close分别是(),所以在装配时,id=#{id}会变为(id=#{id}),在不同的迭代中用separator分割出来。距离就是
select * from test where (id = 1) or (id = 2) or (id = 3)

public List<User> findUsersByIds(List<String> ids);
<select id="findUsersByIds" parameterType="java.util.List" resultType="User">
        select * from test
        <where>
--             select * from test where (id=1) or (id = 2) or (id = 3)
--             collection是循环的类型,item是循环的每一项用id表示
            <foreach collection="list" item="id" open="(" close=")" separator="or">
                id = #{id}
            </foreach>
        </where>
    </select>