MyBatis-动态SQL

一、动态SQL主要使用以下标签:

1、if判断

2、choose(when otherwise):

  分支选择;带了break的swtich-case
  如果带了id就用id查,如果带了lastName就用lastName查;只会进入其中一个。

3、trim 字符串截取(where(封装查询条件), set(封装修改条件))

4、foreach 遍历集合

二、案列

1、<where if结合>

     <!-- 查询员工,要求,携带了哪个字段查询条件就带上这个字段的值 -->
     <!-- public List<Employee> getEmpsByConditionIf(Employee employee); -->
     <select id="getEmpsByConditionIf" resultType="com.atguigu.mybatis.bean.Employee">
         select * from tbl_employee
         <!-- where -->
         <where>
             <!-- test:判断表达式(OGNL)
             OGNL参照PPT或者官方文档。
                    c:if  test
             从参数中取值进行判断
             
             遇见特殊符号应该去写转义字符:
             &&:
             -->
             <if test="id!=null">
                 id=#{id}
             </if>
             <if test="lastName!=null &amp;&amp; lastName!=&quot;&quot;">
                 and last_name like #{lastName}
             </if>
             <if test="email!=null and email.trim()!=&quot;&quot;">
                 and email=#{email}
             </if> 
             <!-- ognl会进行字符串与数字的转换判断  "0"==0 -->
             <if test="gender==0 or gender==1">
                  and gender=#{gender}
             </if>
         </where>
     </select>

  说明:如果where 后面紧跟着and,<where>标签会自动去掉紧跟在后面的第一个and。

2、

     <!--public List<Employee> getEmpsByConditionTrim(Employee employee);  -->
     <select id="getEmpsByConditionTrim" resultType="com.atguigu.mybatis.bean.Employee">
         select * from tbl_employee
         <!-- 后面多出的and或者or where标签不能解决 
         prefix="":前缀:trim标签体中是整个字符串拼串 后的结果。
                 prefix给拼串后的整个字符串加一个前缀 
         prefixOverrides="":
                 前缀覆盖: 去掉整个字符串前面多余的字符
         suffix="":后缀
                 suffix给拼串后的整个字符串加一个后缀 
         suffixOverrides=""
                 后缀覆盖:去掉整个字符串后面多余的字符
                 
         -->
         <!-- 自定义字符串的截取规则
      加上前缀 where 如果最后面有and,则去掉
    
--> <trim prefix="where" suffixOverrides="and"> <if test="id!=null"> id=#{id} and </if> <if test="lastName!=null &amp;&amp; lastName!=&quot;&quot;"> last_name like #{lastName} and </if> <if test="email!=null and email.trim()!=&quot;&quot;"> email=#{email} and </if> <!-- ognl会进行字符串与数字的转换判断 "0"==0 --> <if test="gender==0 or gender==1"> gender=#{gender} </if> </trim> </select>

3、

     <!-- public List<Employee> getEmpsByConditionChoose(Employee employee); -->
     <select id="getEmpsByConditionChoose" resultType="com.atguigu.mybatis.bean.Employee">
         select * from tbl_employee 
         <where>
             <!-- 如果带了id就用id查,如果带了lastName就用lastName查;只会进入其中一个 -->
             <choose>
                 <when test="id!=null">
                     id=#{id}
                 </when>
                 <when test="lastName!=null">
                     last_name like #{lastName}
                 </when>
                 <when test="email!=null">
                     email = #{email}
                 </when>
                 <otherwise>
                     gender = 0
                 </otherwise>
             </choose>
         </where>
     </select>

 

4、

     <!--public void updateEmp(Employee employee);  -->
     <update id="updateEmp">
         <!-- Set标签的使用 -->
         update tbl_employee 
        <set>
            <if test="lastName!=null">
                last_name=#{lastName},
            </if>
            <if test="email!=null">
                email=#{email},
            </if>
            <if test="gender!=null">
                gender=#{gender}
            </if>
        </set>
        where id=#{id} 
<!--         
        Trim:更新拼串
        update tbl_employee 
        <trim prefix="set" suffixOverrides=",">
            <if test="lastName!=null">
                last_name=#{lastName},
            </if>
            <if test="email!=null">
                email=#{email},
            </if>
            <if test="gender!=null">
                gender=#{gender}
            </if>
        </trim>
        where id=#{id}  -->
     </update>

 

5、

     <!--public List<Employee> getEmpsByConditionForeach(List<Integer> ids);  -->
     <select id="getEmpsByConditionForeach" resultType="com.atguigu.mybatis.bean.Employee">
         select * from tbl_employee
         <!--
             collection:指定要遍历的集合:
                 list类型的参数会特殊处理封装在map中,map的key就叫list
             item:将当前遍历出的元素赋值给指定的变量
             separator:每个元素之间的分隔符
             open:遍历出所有结果拼接一个开始的字符
             close:遍历出所有结果拼接一个结束的字符
             index:索引。遍历list的时候是index就是索引,item就是当前值
                           遍历map的时候index表示的就是map的key,item就是map的值
             
             #{变量名}就能取出变量的值也就是当前遍历出的元素
           -->
         <foreach collection="ids" item="item_id" separator=","
             open="where id in(" close=")">
             #{item_id}
         </foreach>
     </select>

 

6、

      <!-- 
          抽取可重用的sql片段。方便后面引用 
          1、sql抽取:经常将要查询的列名,或者插入用的列名抽取出来方便引用
          2、include来引用已经抽取的sql:
          3、include还可以自定义一些property,sql标签内部就能使用自定义的属性
                  include-property:取值的正确方式${prop},
                  #{不能使用这种方式}
      -->
      <sql id="insertColumn">
              <if test="_databaseId=='oracle'">
                  employee_id,last_name,email
              </if>
              <if test="_databaseId=='mysql'">
                  last_name,email,gender,d_id
              </if>
      </sql>
     <!-- 批量保存 -->
     <!--public void addEmps(@Param("emps")List<Employee> emps);  -->
     <!--MySQL下批量保存:可以foreach遍历   mysql支持values(),(),()语法-->
    <insert id="addEmps">
         insert into tbl_employee(
             <include refid="insertColumn"></include>
         ) 
        values
        <foreach collection="emps" item="emp" separator=",">
            (#{emp.lastName},#{emp.email},#{emp.gender},#{emp.dept.id})
        </foreach>
     </insert>

 

7、

     <!-- 这种方式需要数据库连接属性allowMultiQueries=true;
         这种分号分隔多个sql可以用于其他的批量操作(删除,修改) -->
     <insert id="addEmps">
         <foreach collection="emps" item="emp" separator=";">
             insert into tbl_employee(last_name,email,gender,d_id)
             values(#{emp.lastName},#{emp.email},#{emp.gender},#{emp.dept.id})
         </foreach>
     </insert>

 

  说明:separator:分隔符。foreach中间的语句使用“;”分隔。

8、Oracle数据库批量保存:

  Oracle不支持values(),(),()

  Oracle支持的批量方式
    1、多个insert放在begin - end里面
      begin
      insert into employees(employee_id,last_name,email)
      values(employees_seq.nextval,'test_001','test_001@atguigu.com');
      insert into employees(employee_id,last_name,email)
      values(employees_seq.nextval,'test_002','test_002@atguigu.com');
      end;
    2、利用中间表:
     insert into employees(employee_id,last_name,email)
     select employees_seq.nextval,lastName,email from(
     select 'test_a_01' lastName,'test_a_e01' email from dual
     union
     select 'test_a_02' lastName,'test_a_e02' email from dual
     union
       select 'test_a_03' lastName,'test_a_e03' email from dual
     )

     <insert id="addEmps" databaseId="oracle">
         <!-- oracle第一种批量方式 -->
         <!-- <foreach collection="emps" item="emp" open="begin" close="end;">
             insert into employees(employee_id,last_name,email) 
                values(employees_seq.nextval,#{emp.lastName},#{emp.email});
         </foreach> -->
         
         <!-- oracle第二种批量方式  -->
         insert into employees(
             <!-- 引用外部定义的sql -->
             <include refid="insertColumn">
                 <property name="testColomn" value="abc"/>
             </include>
         )
                 <foreach collection="emps" item="emp" separator="union"
                     open="select employees_seq.nextval,lastName,email from("
                     close=")">
                     select #{emp.lastName} lastName,#{emp.email} email from dual
                 </foreach>
     </insert>

 

9、Mybatis两个内置参数

  _parameter:代表整个参数

  单个参数:_parameter就是这个参数
    多个参数:参数会被封装为一个map;_parameter就是代表这个map

  _databaseId:如果配置了databaseIdProvider标签。
  _databaseId就是代表当前数据库的别名oracle

  

<select id="getEmpsTestInnerParameter" resultType="com.atguigu.mybatis.bean.Employee">
              <!-- bind:可以将OGNL表达式的值绑定到一个变量中,方便后来引用这个变量的值 -->
              <bind name="_lastName" value="'%'+lastName+'%'"/>
              <if test="_databaseId=='mysql'">
                  select * from tbl_employee
                  <if test="_parameter!=null">
                      where last_name like #{lastName}
                  </if>
              </if>
              <if test="_databaseId=='oracle'">
                  select * from employees
                  <if test="_parameter!=null">
                      where last_name like #{_parameter.lastName}
                  </if>
              </if>
      </select>
  bind:可以将OGNL表达式的值绑定到一个变量中,方便后来引用这个变量的值

10、抽取可重用的sql片段。方便后面引用

    1、sql抽取:经常将要查询的列名,或者插入用的列名抽取出来方便引用
    2、include来引用已经抽取的sql:
    3、include还可以自定义一些property,sql标签内部就能使用自定义的属性
      include-property:取值的正确方式${prop},
      #{不能使用这种方式}

  

<sql id="insertColumn">
              <if test="_databaseId=='oracle'">
                  employee_id,last_name,email
              </if>
              <if test="_databaseId=='mysql'">
                  last_name,email,gender,d_id
              </if>
      </sql>

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  

posted @ 2017-06-30 11:00  IT-執念  阅读(999)  评论(0编辑  收藏  举报