08.MyBatis动态sql

本文详细介绍了MyBatis中的动态SQL功能,包括if标签实现多条件查询,set标签用于动态更新,foreach标签遍历集合进行条件拼接,以及SQL片段的重用。通过这些方法,可以灵活构建SQL语句,提高代码的可维护性和效率。
摘要由CSDN通过智能技术生成

08.MyBatis动态sql

  • 应用场景
    当我们要根据不同的条件,来执行不同的sql语句的时候,需要用到动态sql。

1. 动态 SQL 之 if

  • 需求
    根据id和username查询,但是不确定两个都有值。

  • UserMapper接口

    public List<User> findByIdAndUsernameIf(User user);
    
  • UserMapper.xml映射

 <!-- 动态sql之if : 多条件查询-->
    <select id="findByIdAndUsernameIf" parameterType="user" resultType="com.lagou.domain.User">
        select * from user
        <!-- test里面写的就是表达式
            <where>: 相当于where 1= 1,但是如果没有条件的话,不会拼接上where关键字
        -->
        <where>
            <if test="id != null">
                and id = #{id}
            </if>
            <if test="username !=null">
                and username = #{username}
            </if>
        </where>

    </select>

2.动态 SQL 之set

需求:动态更新user表数据,如果该属性有值就更新,没有值不做处理。

  • UserMapper接口

    void updateIf(User user);
    
  • UserMapper.xml映射

    set: 在更新的时候,会自动添加set关键字,还会去掉最后一个条件的逗号

<!--动态sql之set : 动态更新-->
    <update id="updateIf" parameterType="user">
        update user
        <!--<set> : 在更新的时候,会自动添加set关键字,还会去掉最后一个条件的逗号 -->
        <set>
            <if test="username != null">
                username = #{username},
            </if>
            <if test="birthday != null">
                birthday = #{birthday},
            </if>
            <if test="sex != null">
                sex = #{sex},
            </if>
            <if test="address != null">
                address = #{address},
            </if>
        </set>
        where id = #{id}
    </update>

3.动态 SQL 之foreach

  • foreach主要是用来做数据的循环遍历

    例如: select * from user where id in (1,2,3) 在这样的语句中,传入的参数部分必须依靠
    foreach遍历才能实现。

  • foreach标签用于遍历集合,它的属性:

    • collection:代表要遍历的集合元素
    • open:代表语句的开始部分
    • close:代表结束部分
    • item:代表遍历集合的每个元素,生成的变量
    • sperator:代表分隔符

    (1)集合:

UserMapper接口:

    List<User> findByList(List<Integer> ids);

UserMaper.xml映射:

<!--   如果查询条件为普通类型 List集合,collection属性值为:collection 或者 list-->
    <select id="findByList" parameterType="list" resultType="user">
        select * from `user`
        <where>
            <foreach collection="collection" open="id in(" close=")" item="id" separator=",">
                #{id}
            </foreach>
        </where>
    </select>

测试代码:

InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        List<User> byList = userMapper.findByList(list);
        for(User user4: byList){
            System.out.println(user4);
        }
        sqlSession.close();

image-20220221233655430

(2)数组

UserMapper接口:

    List<User> findByArray(int[] array);

UserMaper.xml映射

<!--
    如果查询条件为普通类型 Array数组,collection属性值为:array
-->
<select id="findByArray" parameterType="int" resultType="user">
 SELECT * FROM `user`
  <where>
    <foreach collection="array" open="id in(" close=")" item="id"
separator=",">
     #{id}
    </foreach>
  </where>
</select>
  • 测试代码

    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
            int[] arr = new int[3];
            arr[0] = 1;
            arr[1] = 2;
            arr[2] = 9;
            List<User> byArray = userMapper.findByArray(arr);
            for(User user4: byArray){
                System.out.println(user4);
            }
            sqlSession.close();
    

image-20220221235233077

4.SQL片段

应用场景:映射文件中可将重复的sql提取出来,使用时用include引用即可,最终达到sql重用的目的。

//抽取的sql片段
    <sql id="selectUser" >
        select * from `user`
    </sql>
        
<select id="findByArray" parameterType="list" resultType="user">
       <include refid="selectUser"></include>
        <where>
            <foreach collection="array" open="id in(" close=")" item="id" separator=",">
                #{id}
            </foreach>
        </where>
    </select>

5.知识小结

  • MyBatis映射文件配置
<select>:查询
<insert>:插入
<update>:修改
<delete>:删除
<selectKey>:返回主键
<where>:where条件
<if>if判断
<foreach>for循环
<set>:set设置
<sql>:sql片段抽取
MyBatis动态SQL是一种基于OGNL表达式的技术,可以在SQL语句中实现一些逻辑判断。总体上,MyBatis动态SQL主要包含以下几类语句: 1. if语句:用于简单的条件判断。 2. choose语句(相当于Java语言中的switch):包含when和otherwise子句,类似于JSTL中的choose语句。 3. trim语句:在包含的内容上添加前缀或后缀,可以用于动态地拼接SQL语句。 4. where语句:主要用于简化SQL语句中的where条件判断,能够智能地处理and和or,防止多余导致语法错误。 5. set语句:主要用于更新操作。 6. foreach语句:在实现MyBatis的in语句查询时特别有用。 以上是MyBatis动态SQL的几种主要用法,可以根据具体需求选择适合的方式来编写动态SQL语句。 MyBatis Dynamic SQL是一个与MyBatis配套的项目,它解决了MyBatis动态SQL方面的一些缺点,并提供了更灵活、强大的动态SQL功能。该项目可以帮助开发人员更方便地编写复杂的SQL语句,提高开发效率。你可以在官方文档中了解更多关于MyBatis Dynamic SQL的信息。 <span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [真正的Mybatis动态sqlMyBatis Dynamic SQL](https://blog.csdn.net/qq_36534560/article/details/119931287)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [mybatis动态sql及分页](https://blog.csdn.net/hjzhzhshhs/article/details/125241823)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员阿红

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值