zoukankan      html  css  js  c++  java
  • MyBatis中动态SQL元素的使用

    掌握MyBatis中动态SQL元素的使用

    • if
    • choose(when,otherwise)
    • trim
    • where
    • set
    • foreach
    • <SQL>和<include>

    在应用中我们经常会做一些动态的拼接条件,但是如果是JDBC我们可以用程序拼接SQL语句,如果MyBatis,我们可以使用动态SQL语句。例如按照员工姓名和工资来搜索员工信息,如果如果姓名和工资的检索值为空,则忽略这个检索条件。一般来说,我们都会用where 1=1类似这种写法来实现,但是MyBatis就需要动态语句实现。

    1      if元素

    mapper.xml

     1 <select id="selectStudentByCondition" parameterType="student" resultMap="BaseResultMap">
     2         select * from student where 1=1
     3         <!-- 当传入的属性值为空或者空字符串时会忽略掉条件
     4             注意:test中的pojo中的属性名称
     5                  like的使用
     6                  <![CDATA[ ]]>的使用-->
     7         <if test="stuName !=null and stuName != ''">
     8             and stu_name like '%' ||#{stuName}||'%'
     9         </if>
    10         <if test="stuBirthdate != null">
    11             <![CDATA[and stu_birthdate>#{stuBirthdate}]]>
    12         </if>
    13     </select>

    daoImpl.java

     1 @Override
     2 public void testQuery6(Student s){
     3     SqlSession session = fac.openSession();
     4     List<Student> result = session.selectList("student.selectStudentByCondition",s);
     5     for (Student s1 : result) {
     6         System.out.println("s1  id=" + s1.getStuId());
     7         System.out.println("s1  name=" + s1.getStuName());
     8         System.out.println("s1  Birthdate=" + s1.getStuBirthdate());
     9     }
    10     session.close();
    11 }

    测试

    1 public static void main(String[] args) throws Exception {
    2     //创建要保存的学生信息
    3     Student s = new Student();
    4     s.setStuName("zhou");
    5     s.setStuBirthdate(new SimpleDateFormat("yyyy-MM-dd").parse("1991-1-12"));
    6     
    7     StudentDao sdao = new StudentDaoImpl(fac);
    8     sdao.testQuery6(s);
    9 }

    2     choose元素

    choose元素相当于java语句的if … else if …else语句

     1 <!-- 动态SQL:choose标签 -->
     2 <select id="queryByCondition2" parameterType="student " resultMap="BaseResultMap">
     3 select * from student where 1=1
     4 <choose>
     5 <when test="stuName != null and stuName != ''">
     6           and stu_name=#{stuName}
     7 </when>
     8 <when test="stuBirthdate != null">
     9           and stu_birthdate=#{stuBirthdate}
    10 </when>
    11 <otherwise>
    12            and stu_phone=#{stuPhone}
    13 </otherwise>
    14 </choose>
    15 </select>

    3      WHERE元素

    使用where元素会自动根据条件的个数增删where语句and运算符,所以不需要写where 1=1之类的语句

     1 <!-- 动态SQL:where标签 -->
     2 <select id="queryByCondition3" parameterType="student " resultMap="BaseResultMap">
     3 select * from student
     4 <where>
     5 <if test="stuName != null and stuName != ''">
     6     and stu_name=#{stuName}
     7 </if>
     8 <if test="stuBirthdate != null">
     9     and stu_birthdate=#{stuBirthdate}
    10 </if>
    11 <if test="stuPhone != null and stuPhone != ''">
    12     and stu_phone=#{stuPhone}
    13 </if>
    14 </where>
    15 </select>

    4      Trim元素

    trim元素的主要功能是可以在自己包含的内容前加上某些前缀,也可以在其后加上某些后缀,与之对应的属性是prefix和suffix;可以把包含内容的首部某些内容覆盖,即忽略,也可以把尾部的某些内容覆盖,对应的属性是prefixOverrides和suffixOverrides 

     1 <!-- 动态SQL:trim标签 -->
     2 <select id="queryByCondition4" parameterType="student " resultMap="BaseResultMap">
     3 select * from student
     4 <trim prefix="where" prefixOverrides="and|or">
     5 <if test="stuName != null and stuName != ''">
     6     and stu_name=#{stuName}
     7 </if>
     8 <if test="stuBirthdate != null">
     9     and stu_birthdate=#{stuBirthdate}
    10 </if>
    11 <if test="stuPhone != null and stuPhone != ''">
    12     or stu_phone=#{stuPhone}
    13 </if>
    14 </trim>
    15 </select>

    5      foreach元素

    foreach的主要用在构建in条件中,它可以在SQL语句中进行迭代一个集合。foreach元素的属性主要有item,index,collection,open,separator,close。item表示集合中每一个元素进行迭代时的别名,index指定一个名字,用于表示在迭代过程中,每次迭代到的位置,open表示该语句以什么开始,separator表示在每次进行迭代之间以什么符号作为分隔符,close表示以什么结束,在使用foreach的时候最关键的也是最容易出错的就是collection属性,该属性是必须指定的,但是在不同情况下,该属性的值是不一样的,主要有以下3种情况。

    1. 如果传入的是单参数且参数类型是一个List的时候,collection属性值为list
    2. 如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array
    3. 如果传入的参数是多个的时候,我们就需要把它们封装成一个Map了,当然单参数也可以封装成map,实际上如果你在传入参数的时候,在MyBatis里面也是会把它封装成一个Map的,map的key就是参数名,所以这个时候collection属性值就是传入的List或array对象在自己封装的map里面的key

    Mapper.xml

     1 <!-- 动态SQL:传入Array数组 -->
     2     <select id="queryByInArray" resultMap="BaseResultMap">
     3        select * from student 
     4     <if test="array.length>0">
     5         where stu_id in 
     6         <foreach collection="array" index="i" item="stuId" open="(" close=")" separator=",">
     7             #{stuId}
     8         </foreach>
     9     </if>
    10     </select>
    11 <!-- 动态SQL:传入List集合 -->
    12     <select id="queryByInList" resultMap="BaseResultMap">
    13         select * from student
    14         <if test="list.size()>0">
    15             where stu_id in
    16             <foreach collection="list" index="i" item="stuId" open="("
    17                 close=")" separator=",">
    18                 #{stuId}
    19             </foreach>
    20         </if>
    21     </select>
    22 <!-- 动态SQL:传入Map集合包含List集合 -->
    23     <select id="queryByInMap" resultMap="BaseResultMap">
    24         select * from student
    25         <if test="ids.size()>0">
    26             where stu_id in
    27             <foreach collection="ids" index="i" item="stuId" open="("
    28                 close=")" separator=",">
    29                 #{stuId}
    30             </foreach>
    31         </if>
    32     </select>

    DaoImpl.java

     1 @Override
     2     public void testQuery7(){
     3         SqlSession session = fac.openSession();
     4         int[] ids = new int[]{2};
     5         List<Student> list = session.selectList("student.queryByInArray",ids);
     6         for (Student item : list) {
     7             System.out.println(item);
     8         }
     9         session.close();
    10     }
    11 @Override
    12     public void testQuery8(){
    13         SqlSession session = fac.openSession();
    14         List ids = new ArrayList();
    15         ids.add(2);
    16         ids.add(3);
    17         ids.add(4);
    18         List<Student> list = session.selectList("student.queryByInList",ids);
    19         for (Student item : list) {
    20             System.out.println(item);
    21         }
    22 session.close();
    23     }
    24     @Override
    25     public void testQuery8(){
    26         SqlSession session = fac.openSession();
    27         List ids = new ArrayList();
    28         ids.add(2);
    29         ids.add(3);
    30         Map map = new HashMap();
    31         map.put("ids", ids);
    32         List<Student> list = session.selectList("student.queryByInMap",map);
    33         for (Student item : list) {
    34             System.out.println(item);
    35         }
    36         session.close();
    37     }

    6      set元素

    set元素主要是用在更新操作的时候,它的主要功能和where元素其实是差不多的,主要是在包含的语句前输出一个set,然后如果包含的语句是以逗号结束的话将会把该逗号忽略,如果set包含的内容为空的话则会出错。有了set元素我们就可以动态的更新那些修改了的字段。

     1     <!-- 动态SQL:set更新 -->
     2 <update id="updateByCondition" parameterType="student">
     3     update student
     4     <set>
     5         <if test="stuName!=null and stuName!=''">
     6             stu_name=#{stuName},
     7         </if>
     8         <if test="stuBirthdate!=null">
     9             stu_birthdate=#{stuBirthdate},
    10         </if>
    11         <if test="stuPhone!=null and stuPhone!=''">
    12             stu_phone=#{stuPhone}
    13         </if>
    14     </set>
    15     where stu_id=#{stuId}
    16 </update>

    7      <SQL>和<include>

    可以编写一些语句片段<SQL>标签,然后在其他语句标签汇中用<include>引用,这样可以是SQL语句片段得到重用

    示例:

    <!-- SQL片段 -->
    <SQL id="SQL_select">
             select *
     </SQL>
    <SQL id="SQL_count">
             select count(*)
    </SQL>
    
    <!-- 包含SQL片段 -->
    <select id="query6" resultMap="BaseResultMap">
             <include refid="SQL_select"/>
             from student
    </select>
    
    <select id="query7" resultType="java.lang.Integer">
             <include refid="SQL_count"/>
             from student
    </select> 
  • 相关阅读:
    Day015 PAT乙级 1013 数素数
    Day014 PAT乙级 1012 数字分类
    Day013 PAT乙级 1007 素数对猜想
    Day012 PAT乙级 1005 继续(3n+1)猜想
    Day011 PAT乙级 1003 我要通过
    Day010 PAT乙级 1002 写出这个数
    Day009 洛谷 P5707 上学迟到
    Day008 洛谷 P2181 对角线
    Day007 Java异常处理
    Fetch()
  • 原文地址:https://www.cnblogs.com/zhouyeqin/p/8359546.html
Copyright © 2011-2022 走看看