• --------------------------------MaBatis动态sql--------------------------


    1)动态SQL基于OGNL的表达式,可以方便的在SQL语句中实现某些逻辑,用于实现动态SQL的元素如下:

      (1)if:利用if实现简单的条件选择。

      (2)choose(when,otherwise):相当于Java中的switch语句。通常与when和otherwise搭配。

      (3)where :简化SQL语句中where的条件判断,主要用来简化SQL语句中的where条件判断,并能智能的处理and和          or,不必要担心关键字导致的语法错误。

           (4)set:解决动态更新语句

      (5)trim:可以灵活的去除多余的关键字。

      (6)foreach:迭代一个集合,通常用于in条件

    2) 

    现在前台有个表单!
    表单中有三项条件 来查询 符合条件的学生!
    01.根据学生姓名查询
    02.根据老师姓名查询
    03.根据年级名称查询
    
    针对于上述的情况,我们发现三个查询条件 不在同一个表中!
    
    第一种情况:
    
      把学生姓名,老师姓名,年级名称封装成一个Map集合
      Map<String.Object>  map=new  HashMap<String,Object>();
      //把三个条件放进map
      map.put("studentName",学生姓名);
      map.put("teacherName",老师姓名);
      map.put("gradeName",年级名称);
      //调用dao层方法
      dao.xxx(map);
    
      然后去mapper.xml文件中执行sql语句
    
      select s.name,s.id,s.age  from  student s,teacher t,grade g
      where s.tId=t.id and s.gId=g.id
      and s.name=#{studentName}   //开始使用map中的key
      and t.name=#{teacherName}
      and g.name=#{gradeName}
    
    
    第二种情况:
    
       用户可以传递几个参数,我们在方法定义时就书写几个形参!
    
       在接口中书写方法
    
       List<Student> selectStduentsByCondition(String stuName,String teacherName,String gradeName);
    
      在mapper.xml文件中书写sql
    
     select s.name,s.id,s.age  from  student s,teacher t,grade g
      where s.tId=t.id and s.gId=g.id
      and s.name=#{0}   //开始使用参数的下标
      and t.name=#{1}
      and g.name=#{2}
    
    
    
    总结#{}中可以存放的内容
    
    01. 当参数是对象的时候,存放的是对象的属性
    02. 存放map时的注意点
        001.当参数是map集合时,存放的是map的key
        002.如果map的value是对象时,存放的是对象的属性
    03.如果传递一个参数,存放的是占位符
    04.如果传递多个参数,存放的是参数对应的下标,从0开始
    <mapper namespace="com.xdf.dao.StudentDao"> <!--必须是对应的dao接口的全类名-->
    
        <!--
          我们在前台表单中  有 三个输入框!
          用户输入了几个???我们不知道
          #{stuName}#{stuAge}
          必须是map集合中的key
        <select id="selectStduentsByMap" resultType="Student">
         select id,name,age from student
         where name like  concat('%',#{stuName},'%')
         and  age>#{stuAge}
        </select> -->
    
        <select id="selectStduentsByMap" resultType="Student">
            select id,name,age from student
            where name like  concat('%',#{stuName},'%')
            and  age>#{stuAge}
            AND  id>#{student.id}
        </select>
    
        <!--按照参数的下标进行封装   下标从0开始-->
        <select id="selectStduentsByCondition" resultType="Student">
            select id,name,age from student
            where name like  concat('%',#{0},'%')
            and  age>#{1}
        </select>
    
    
    </mapper>

     上面都是写死的。没用动态标签,看下面

    <mapper namespace="com.xdf.dao.StudentDao"> <!--必须是对应的dao接口的全类名-->
    
       <!-- 01.用户传递一个Student对象  但是我们不知道用户对那些属性赋了值
          注意点  特殊字符的使用
          && (逻辑与)  必须换成 (and) 或者 (&amp;)
          where 1=1  每次拼接查询都会 执行 影响性能
       -->
          <select id="selectStudentsByIf" resultType="Student">
             SELECT  id,name,age from  student  where 1=1
             <if test="name!=null and name!=''">
                   and  name like concat('%',#{name},'%')
             </if>
             <if test="age &gt; 0">
                   and  age > #{age}
             </if>
          </select>
    
    
    
        <!--where 标签 替换where 1=1-->
          <select id="selectStudentsByWhere" resultType="Student">
             SELECT  id,name,age from  student
              <where>
                  <if test="name!=null and name!=''">
                      and  name like concat('%',#{name},'%')
                  </if>
                  <if test="age &gt; 0">
                      and  age > #{age}
                  </if>
              </where>
          </select>
    
    
        <!--
        choose标签    类似java中的switch
           01.当我们的年龄不为空 按照年龄查询
           02.当我们的姓名不为空 按照姓名查询
           03.如果都会空 执行otherwise
              如果没有otherwise标签,会查询所有
           04.如果多个条件满足,执行第一个满足的when
        如果条件只允许执行一个  就是用choose
          因为值执行一个sql  所以不需要加and
        想多个条件执行,使用if
          因为有多个sql需要拼接 所以 不能省略and
        在mybatis中 底层不会给我们生成and
        -->
        <select id="selectStudentsByChoose" resultType="Student">
              SELECT  id,name,age from  student
            <where>
               <choose>
                    <when test="name!=null and name!=''">
                          name like concat('%',#{name},'%')
                    </when>
                    <when test="age > 0">
                          age>#{age}
                    </when>
                   <otherwise>
                     1!=1
                  </otherwise>
               </choose>
            </where>
        </select>
    
    
        <!-- foreach 遍历数组
        我们之前在mysql中查询的语句
        SELECT  id,NAME,age FROM student   WHERE id IN (12,13,14)
        问题??
        01.我们知道用户输入的是12,13,14,吗???
        02.1213,14是动态获取的  是dao中方法的参数 int [] nums
        03.nums的每个元素 就是  12,13,14
        04.用户是不是有可能一个值都没有传入
        05.只要是数组    在mybatis对应的值就是array
         -->
        <select id="selectStudentsByForeachArray" resultType="Student">
            SELECT  id,NAME,age FROM student
            <if test="array.length>0"> /*证明用户有值传入*/
                 where id IN         /*(12,13,14) 动态的拼接*/
                <foreach collection="array" item="varId" open="(" separator="," close=")">
                    #{varId}
                </foreach>
            </if>
        </select>
    
        <!--遍历 List集合  在mybatis对应的值就是list-->
        <select id="selectStudentsByForeachList" resultType="Student">
            SELECT  id,NAME,age FROM student
            <if test="list.size>0">
                 where id IN
                <foreach collection="list" item="varId" open="(" separator="," close=")">
                    #{varId}
                </foreach>
            </if>
        </select>
        <!--遍历 Student集合 -->
        <select id="selectStudentsByForeachStudent" resultType="Student">
            SELECT  id,NAME,age FROM student
            <if test="list.size>0">
                 where id IN
                <foreach collection="list" item="stu" open="(" separator="," close=")">
                    #{stu.id} /*必须是对象中的属性*/
                </foreach>
            </if>
        </select>
    
        <!--遍历 map集合   map集合在mybatis中没有设置对应的值
        myMap就是我们dao层方法的@Param("myMap")
        遍历myMap.keys 就是获取map集合中的所有key的集合
        -->
        <select id="selectStudentsByForeachMap" resultType="Student">
            <include refid="seleteStudents"/>
                where id IN
            <if test="myMap.keys.size>0">
                <foreach collection="myMap.keys"  item="mapKey" open="(" separator="," close=")">
                    #{mapKey}
                </foreach>
            </if>
        </select>
    
        <!--
         sql片段:  提取mapper文件中所有的sql公共部分
        -->
    
        <sql id="seleteStudents">
              SELECT  id,NAME,age FROM student
        </sql>
    
    
    </mapper>

    4)使用if+trim实现多条件查询

         

    trim 属性

                    prefix:前缀覆盖并增加其内容

                    suffix:后缀覆盖并增加其内容

                    prefixOverrides:前缀判断的条件

                    suffixOverrides:后缀判断的条件

    <where> <if>  
    <if>标签单独使用,如下
    
    <select id="selectSudent" parameterType="String" resultType="java.util.List">
        SELECT * FROM student
        <if test="name!=null and name!=''">
            WHERE 
              name like CONCAT('%',#{name},'%')
        </if></select>
    
    如果name为空或空串 则进行全部查询,效率会下降
    
    
    
    当进行多条件下查询是,<where> <if>  可以提高查询速度 和优化查询语句
    <select id="selectSudent" parameterType="String" resultType="java.util.List">
        SELECT name,sex FROM student
        <where>
            <if test="name!=null and name!=''">
                   name like CONCAT('%',#{name},'%')
            </if>        <if test="sex!=null and sex!=''">            AND sex=#{sex}        </if>    </where></select>
    
    
    
    
    <set> <if>
    使用
    <update id="updateStudent" parameterType="com.frank.Student">
        UPDATE student
        <set>
            <if test="name!=null and name!=''">
                name= #{name},
            </if>
            <if test="sex!=null and sex!=''">
                 sex=#{sex}
            </if>
        </set>
        WHERE no=#{no}
    </update>
    
    
    
    <trim> <if>
    我个人感觉<trim>标签就是<where><set>结合 他同时具有两者的功能
    
    <select id="selectSudent" parameterType="String" resultType="java.util.List">
        SELECT name,sex FROM student
        <trim prefix="WHERE" prefixOverrides="AND|OR">
            <if test="name!=null and name!=''">
             name like CONCAT('%',#{name},'%')
            </if>
            <if test="sex!=null and sex!=''">
                AND sex=#{sex}
            </if>
        </trim>
    </select>
    
    <update id="updateStudent" parameterType="com.frank.Student">
        UPDATE student
        <trim prefix="SET" suffixOverrides=",">
            <if test="name!=null and name!=''">
                name= #{name},
            </if>
            <if test="sex!=null and sex!=''">
                 sex=#{sex}
            </if>
        </trim>
        WHERE no=#{no}
    </update>
  • 相关阅读:
    Java.io 包(字节流)
    Java 集合框架(常用数据结构)
    Java.util 包(Date 类、Calendar类、Random类)
    Java.lang 包 (包装类、String类、Math类、Class类、Object类)
    Java 多态(接口)
    maxcompute troubleshoot
    maxcompute
    文件命名
    weblogic修改ServerName
    设计模式---策略模式
  • 原文地址:https://www.cnblogs.com/laosunlaiye/p/7586867.html
Copyright © 2020-2023  润新知