动态SQL

mybatis中特征之一是支持动态SQL

通过标签的形式来动态编写SQL,根据业务逻辑来动态的进行SQL拼接功能

mybatis提供九种动态SQL标签:trim/if/where/set/foreach/choose/when/otherwise/bind

执行原理:使用OGNL从SQL参数对象中动态计算表达式的值,根据表达式的值动态拼接SQL,以此完成动态SQL的功能

一、标签

1.1 if标签

动态SQL通常作为where子句的一部分
常用于查询、插入、更新等操作
场景:根据姓名、性别、姓名和性别查询相应的数据

        <if test="Sname!=null">
            Sname=#{Sname}
        </if>

if 表达式中判断参数是否传递:if test属性,该属性必填,为true或者false,test使用OGNL表达式处理,返回为true则进入if标签中的SQL,返回为false则不会进入标签中

  <!--
    第一种条件:name和Sex都传递:select * from student where Sname=XX and Ssex=XXX
    第二种条件:只传递name:select * from student where Sname=XX
    第三种条件:只传递Sex:select * from student where Ssex=XXX
    第四种条件:不传递参数:select * from student
    -->
   <select id="selectStudentByNameOrSex" parameterType="student" resultMap="studentMap">
        select * from student where 1=1 
        <if test="Sname!=null">
            and Sname=#{Sname}
        </if>
        <if test="Ssex!=null">
            and Ssex=#{Ssex}
        </if>
    </select>

第一种条件:传递两个参数:
在这里插入图片描述
第二种:只传递Sname属性
在这里插入图片描述
第三种条件:只传递Ssex属性
在这里插入图片描述
第四种条件:不传递属性
在这里插入图片描述

1.2 where标签

where标签作用:

 <select id="selectStudentByNameOrSex" parameterType="student" resultType="student">
        select * from student
        <where>
            <if test="Sname!=null">
                and Sname=#{Sname}
            </if>
            <if test="Ssex!=null">
                and Ssex=#{Ssex}
            </if>
        </where>
    </select>

第一种条件:传递两个参数:
在这里插入图片描述
第二种条件:只传递Sname属性
在这里插入图片描述
第三种条件:只传递Ssex属性
在这里插入图片描述
第四种条件:不传递属性
在这里插入图片描述
where表达式一般和if表达式一块使用,如果条件一个都不满足,则不拼接where条件,如果有一个或者多个表达式成立,where会直接拼接在SQL语句上,并且紧随的where表达式的and/or会忽略掉

1.3 trim标签

mybatis提供trim标签一般适用于去除SQL语句中多余的and关键字,逗号,或者给SQL语句拼接“where”、“set”以及values等,可用于选择性插入、更新、删除或者条件查询等操作,where和set标签都可以通过trim标签来实现
trim属性:
在这里插入图片描述
trim标签可以和上面的where实现相同的功能

 <select id="selectStudentByNameOrSex" parameterType="student" resultType="student">
        select * from student
        <trim prefix="where" prefixOverrides="and">
            <if test="Sname!=null">
                and Sname=#{Sname}
            </if>
            <if test="Ssex!=null">
                and Ssex=#{Ssex}
            </if>
        </trim>
    </select>

1.4 foreach标签

适用于批量操作

场景1:通过一批id来查询student

select * from student where SID in(1,2,3,4,5);
List<Student> selectBatchQueryStudent(List<Integer> idx);
 <!--
    select * from student where SID in(1,2,3,4,5);
    foreach表达式
    collection属性:必填,指定参数入参类型
                    参数类型可以是 (列表:List 数组:array HashMap:map)
    item属性:起名字,给集合中单个元素起名称
    open属性:开始字符串
    close属性:结束字符串
    separator属性:分隔符
    index属性:索引的属性名,在集合数组下值为当前的索引值
    -->
    <select id="selectBatchQueryStudent" resultType="student">
        select * from student where SID in 
        <foreach collection="List" item="id" open="(" close=")" separator=",">
            #{id}
        </foreach>
    </select>

执行结果SQL

select * from student where SID in ( ? , ? , ? , ? , ? , ? ) 

二、模糊匹配

需求:查询student表中Sname含有w的的信息

select * from student where Sname like "%w%";

mybatis模糊匹配如何写?

方式一:直接在参数上进行模糊匹配

接口方法:

 List<Student> selectStudentBySname(String name);

XML配置文件:

    <select id="selectStudentBySname" parameterType="String" resultType="student">
        select * from student where Sname like #{name}
    </select>

测试方法:

    @Test
    public void selectStudentBySname(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
        List<Student> students = studentMapper.selectStudentBySname("%r%");
        for(Student s:students){
            System.out.println(s);
        }
        sqlSession.commit();
    }

执行结果:
在这里插入图片描述

方式二:mysql中提供的方法concat()拼接

XML配置文件:

  <select id="selectStudentBySname" parameterType="String" resultType="student">
        select * from student where Sname like concat('%',#{name},'%')
    </select>

测试方法:

  public void selectStudentBySname(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
        List<Student> students = studentMapper.selectStudentBySname("w");
        for(Student s:students){
            System.out.println(s);
        }
        sqlSession.commit();
    }

执行结果:
在这里插入图片描述

方式三:bind表达式处理

接口方法:

 List<Student> selectStudentBySname(Student Sname);

XML配置文件:

  <select id="selectStudentBySname" parameterType="Student" resultType="student">
        <bind name="ln" value="'%'+Sname+'%'"/>
        select * from student where Sname like #{ln}
    </select>

注意:bind表达式中参数必须具有getter方法,底层是通过OGNL表达式进行解析的,该表达式通过属性的getter方法进行获取值
执行结果:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值