--------------------------------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.12,13,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>
时间: 2024-08-01 16:49:04

--------------------------------MaBatis动态sql--------------------------的相关文章

MyBatis4:动态SQL

什么是动态SQL MyBatis的一个强大特性之一通常是它的动态SQL能力.如果你有使用JDBC或其他相似框架的经验,你就明白条件串联SQL字符串在一起是多么地痛苦,确保不能忘了空格或者在列表的最后的省略逗号,动态SQL可以彻底处理这种痛苦. 通常使用动态SQL不可能是独立的一部分,MyBatis当然使用一种强大的动态SQL语言来改进这种情形,这种语言可以被用在任意映射的SQL语句中. 动态SQL元素和使用JSTL或其它相似的基于XML的文本处理器相似,在MyBatis之前的版本中,有很多元素需

MyBatis动态SQL小结

p.MsoNormal,li.MsoNormal,div.MsoNormal { margin: 0cm; margin-bottom: .0001pt; text-align: justify; font-size: 10.5pt; font-family: 等线 } .MsoChpDefault { font-family: 等线 } div.WordSection1 { } ol { margin-bottom: 0cm } ul { margin-bottom: 0cm } Mybati

笔记:MyBatis 动态SQL

有时候,静态的SQL语句并不能满足应用程序的需求.我们可以根据一些条件,来动态地构建SQL语句.例如,在Web应用程序中,有可能有一些搜索界面,需要输入一个或多个选项,然后根据这些已选择的条件去执行检索操作.在实现这种类型的搜索功能,我们可能需要根据这些条件来构建动态的SQL语句.如果用户提供了任何输入条件,我们需要将那个条件 添加到SQL语句的WHERE子句中. MyBatis通过使用<if>,<choose>,<where>,<foreach>,<

MyBatis 动态sql详解

MyBatis的动态sql语句 1.if 条件 2.choose , when 和 otherwise条件 3.where 条件 where条件:1.自动加上where.2.如果where子句以and或者or开头,则自动删除第一个and或者or..所以我们不需要自己加where 4.trim 条件 trim条件和where条件类似但是功能更强大:不仅可以替换掉子句开头的and或者or,还提供了加前缀和后缀的功能. 5.forEach循环 6.set 条件 set条件:自动加上set,自动去除最后

db2存储过程动态sql被截断

编写存储过程,使用动态sql时,调试时发现变量赋值后被截断. 关键代码如下: 实现的效果是先把上下游做对比的sql语句和相关参数存入RKDM_DATA_VOID_RULE, 执行存储过程后把两个sql语句得出的结果插入另一张结果表RKDM_DATA_VOID_CHK_REST. 建表语句: CREATE TABLE RKDM_DATA_VOID_CHK_REST ( DATA_DT DATE, ORDR_NUM INTEGER, CHK_BIG_CLS VARCHAR(256), DATA_PR

mybatis入门-动态sql

什么是动态sql 判断的动态sql mybatis核心就是对sql语句进行灵活操作,通过表达式进行判断,对sql进行灵活拼接.组装. 现有需求如下:需要查询用户,输入的是用户类,如果用户的性别类不为空,则将性别作为查询条件之一,如果用户的姓名不为空,则将用户姓名作为查询条件之一.如果用户两个属性都为空,则查询所有用户. 我们知道,在mapper中,我们的传入参数只有一个,多个参数只能通过包转类来实现,现在这种问题怎么解决呢?答案就是在xml文件中加入判断,使sql语句动态生成.刚才的需求所对应的

MyBatis的动态SQL详解

MyBatis的动态SQL是基于OGNL表达式的,它可以帮助我们方便的在SQL语句中实现某些逻辑,本文详解mybatis的动态sql,需要的朋友可以参考下 MyBatis 的一个强大的特性之一通常是它的动态 SQL 能力.如果你有使用 JDBC 或其他 相似框架的经验,你就明白条件地串联 SQL 字符串在一起是多么的痛苦,确保不能忘了空 格或在列表的最后省略逗号.动态 SQL 可以彻底处理这种痛苦. 通常使用动态SQL不可能是独立的一部分,MyBatis当然使用一种强大的动态SQL语言来改进这种

动态SQL

一 动态SQL /* 1.动态SQL概念的内涵 2.实现动态SQL的元素 3.if语句节点 4.choose(when,otherwise)语句节点 5.where节点 6.trim节点 7.set节点(update的set子句) 8.foreach节点 */ 1.动态SQL概念的内涵 MyBatis 最强大的特性之一就是它的动态语句功能,使用动态SQL完成多条件查 询.MyBatis的动态SQL是基于OGNL表达式的,它可以帮助我们方便的在SQL 语中实现某些逻辑. 2.实现动态SQL的元素

mybatis——动态sql

MyBatis的动态SQL是基于OGNL表达式的,它可以帮助我们方便的在SQL语句中实现某些逻辑. MyBatis中用于实现动态SQL的元素主要有: if choose(when,otherwise) trim where set foreach if就是简单的条件判断,利用if语句我们可以实现某些简单的条件选择.先来看如下一个例子: 01 <select id="dynamicIfTest" parameterType="Blog" resultType=&

8.mybatis动态SQL模糊查询 (多参数查询,使用parameterType)

多参数查询,使用parameterType.实例: 用户User[id, name, age] 1.mysql建表并插入数据 2.Java实体类 public class User { public User() { } public User(int id, String name, int age) { super(); this.id = id; this.name = name; this.age = age; } private int id; private String name;