MyBatis动态SQL的使用

各位大佬光临寒舍,希望各位能赏脸给个三连,谢谢各位大佬了!!! 

目录

1.问题的引出

2.动态SQL

案例一

案例二

用if标签 

用where标签

使用where 1=1 

 案例三

案例四

​编辑

小结 

总结 


1.问题的引出

我们在使用MyBatis的时候可能会产生这样一个疑问。如果我们想要插入的参数(当然不仅仅是插入),达不到原SQL语句的要求我们输入的参数数量怎么办。如:

insert into mybatis(user_name,password,age,gender,phone) 
 values(#{username},#{password},#{age},#{gender},#{phone});

但是这时候我们只想输入username,password和age。如果直接只输入这三个就会报错

如果把gender和phone设置为null,则结果又和预期不同(想要默认值但是数据库显示为null或者根本不能改为null值)

这时候就需要动态SQL来帮我们解决类似的问题。

2.动态SQL

动态SQL主要是引入了if,trim,where,set,foreach这五个标签来解决参数数量不对应的问题,我们先讲XML的实现方法,注解方法非常难用,我会在后面带过,原理都差不多。那让我们在几个案例中了解这几个标签吧!

案例一

使用insert语句任意插入username,password,age,gender,phone这几个字段

在这里我们使用if标签,和普通SQL语句一样,我们要先创建方法和insert标签:

    <insert id="insertDP">
    </insert>

这时候我们把标签里的内容加上if标签,这个标签和Java中的if逻辑上是一样的,都是判断,我们这里只需要判断Java中类的这个属性是否为null即可。方法比较复杂要一条一条判断,代码如下:

    <insert id="insert">
        insert into mybatis(user_name,password,age,gender,phone)
        values(#{username},#{password},#{age},#{gender},#{phone})
    </insert>
    <insert id="insertDP">
        insert into mybatis(
        <if test="username!=null">
            user_name
        </if>
        <if test="password!=null">
            ,password
        </if>
        <if test="age!=null">
            ,age
        </if>
        <if test="gender!=null">
            ,gender
        </if>
        <if test="phone!=null">
            ,phone
        </if>
        )
        values(
        <if test="username!=null">
            #{username}
        </if>
        <if test="password!=null">
            ,#{password}
        </if>
        <if test="age!=null">
            ,#{age}
        </if>
        <if test="gender!=null">
            ,#{gender}
        </if>
        <if test="phone!=null">
            ,#{phone}
        </if>
        )
    </insert>

接下来我们测试一下不设置age,测试代码如下:

@Test
    void testSelectDP() {
        StudentInfo studentInfo=new StudentInfo();
        studentInfo.setUsername("laoba");
        studentInfo.setPassword("123321");
        studentInfo.setPhone("123321");
        studentInfoDao2.insertDP(studentInfo);
    }

可以看到我们的代码执行成功了 。

但是这时候有个问题,如果我们没有输入username那么语句就会多一个逗号,导致badSQL,原因也很简单,大家看看上述代码逻辑肯定就懂了。

那么如何解决呢,我们可以使用trim标签,这个标签可以给字符串去除前面和后面的指定字符,还能指定增加前面和后面的指定字符。代码如下:

    </insert>
    <insert id="insertDP">
        insert into mybatis
        <trim prefix="(" prefixOverrides="," suffix=")">
            <if test="username!=null">
                user_name
            </if>
            <if test="password!=null">
                ,password
            </if>
            <if test="age!=null">
                ,age
            </if>
            <if test="gender!=null">
                ,gender
            </if>
            <if test="phone!=null">
                ,phone
            </if>
        </trim>
        <trim prefix="values(" suffix=")" prefixOverrides="," >
            <if test="username!=null">
                #{username}
            </if>
            <if test="password!=null">
                ,#{password}
            </if>
            <if test="age!=null">
                ,#{age}
            </if>
            <if test="gender!=null">
                ,#{gender}
            </if>
            <if test="phone!=null">
                ,#{phone}
            </if>
        </trim>
    </insert>

不出所料我们不用名字也把这条数据添加进数据库了。 

案例二

使用查询语句任意查询username,password,age这几个字段

在这里我们可以像上面一样用if标签来解决: 

<select id="selectDP" resultMap="StudentMap">
        select * from mybatis
        <trim prefix="where" suffixOverrides="and">
            <if test="username!=null">
                user_name=#{username} and
            </if>
            <if test="id!=null">
                id=#{id} and
            </if>
            <if test="age!=null">
                age=#{age}
            </if>
        </trim>
    </select>

但是这时候我们会发现,如果我们没有筛选条件就会多出一个where,这时候有三种解决办法。

用if标签 

用if标签判断内容是否全为空,这个方法需要判断所有条件是否都不存在,比较麻烦。所以我们就引入了第二种方法,和if标签功能一样。

用where标签

where标签会自动在没有内容的时候取消where关键字,并且where标签会总动去除末尾and,也会在前面自动加where,是专门服务于where关键字的:

<select id="selectDP" resultMap="StudentMap">
        select * from mybatis
        <where>
            <if test="username!=null">
                user_name=#{username} and
            </if>
            <if test="id!=null">
                id=#{id} and
            </if>
            <if test="age!=null">
                age=#{age}
            </if>
        </where>
    </select>
使用where 1=1 

这个where 1=1的方法是程序员想出来的,这样就算没有任何条件也可以执行sql语句.因为1=1是恒成立的:

<select id="selectDP" resultMap="StudentMap">
        select * from mybatis
        where 1=1
            <if test="username!=null">
                user_name=#{username} and
            </if>
            <if test="id!=null">
                id=#{id} and
            </if>
            <if test="age!=null">
                age=#{age}
            </if>      
    </select>

 案例三

使用更新语句任意更新username,age这几个字段

还是一样,我们可以用if标签和trim标签来解决,和上面一样,这里我就不再多赘述了 ,我们这里了解一下update标签即可,它会自动加一个set,并且去除句首或句尾的逗号:

<update id="updateDP">
        update mybatis
        <set>
            <if test="username!=null">
                user_name=#{username} ,
            </if>
            <if test="age!=null">
                age=#{age}
            </if>
        </set>
        where id=#{id}
    </update>
    @Test
    void updateDP() {
        StudentInfo studentInfo=new StudentInfo();
        studentInfo.setId(7);
        studentInfo.setAge(1);
        studentInfo.setUsername("333");
        studentInfoDao2.updateDP(studentInfo);
    }

 

案例四

搜索一个集合对应的所有的id

这里我们需要使用foreach标签:

    <select id="selectList" resultType="com.mybatis.demomybatis.demos.model.StudentInfo">
        select * from mybatis
        where id in
        <foreach collection="list" open="(" close=")" separator="," item="id">
            #{id}
        </foreach>
    </select>

 这里的conllection表示集合的名字也可以直接输入collection(只有一个集合),open表示开头,close表示结尾,它们都是添加字符的属性,item是给集合元素命个名,可以下面使用。

我们测试一下试试:

    @Test
    void selectList() {
        List<Integer> ids= Arrays.asList(6, 7);
        System.out.println(studentInfoDao2.selectList(ids));
    }

小结 

我们算是把常用的标签讲完了,事实上还有两个标签sql和include,我在这直接一笔带过好了。sql就相当于把代码片段模板化,可以用include提取。就比如酱紫:

<sql id="select">
        select * from mybatis
    </sql>
    <select id="selectTestInclude" resultType="com.mybatis.demomybatis.demos.model.StudentInfo">
        <include refid="select"></include>
    </select>

 我们在第四行的select语句中就可以直接使用include来使用sql写好的模板(通过id调用)。

我们测试一下试试:

可以看到程序成功运行成功了。

总结 

MyBatis的动态SQL像是JavaScript语言,但是我们还是很容易去理解的,毕竟计算机语言逻辑是互通的。动态SQL在日常开发中还是经常遇到的,所以我们程序猿要好好掌握呀!如果想偷懒建议大家去了解一下MybatisGenerator工具,可以自动生成sql的XML文件。那我们今天的学习旅程就到这啦,咱们下期再见!!!

制作不易,望各位大佬赏个脸,给个三连吧!!谢谢各位大佬了!!!

 

  • 46
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 15
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值