mybatis-动态sql

mybatis-动态sql

尚硅谷mybatis实战

• if:判断
• choose (when, otherwise):分支选择;
• trim 字符串截取(where(封装查询条件), set(封装修改条件))
• foreach 遍历集合
**

1、if的使用(&OGNL):

<!-- test:判断表达式(OGNL)
	  	 c:if  test
	 	从参数中取值进行判断
	 	遇见特殊符号应该去写转义字符:
	 	&:(&amp)          
	 	“:&quot;
-->
	 	<if test="id!=null">
	 		id=#{id}
	 	</if>
	 	<if test="lastName!=null &amp;&amp; lastName!=&quot;&quot;">
	 		and last_name like #{lastName}
	 		
	 	<!-- ognl会进行字符串与数字的转换判断  "0"==0 -->
	 	<if test="gender==0 or gender==1">
	 	 	and gender=#{gender}
	 	</if>
  • 在if查询时,如果某些条件没带可能sql拼装会有问题
    (例如出现select * from tbl_employee where and last_name=?这种问题)
    解决方案:
    (1)给where后加入 1=1永真判断。
select * from tbl_employee
        <!--test:判断表达式-->
       where 1=1
        <if test="id!=null">
            id=#{id}
        </if

(2)mybatis使用where标签(封装查询条件)来将所有的查询条件包括在内。

select * from tbl_employee
        <!--test:判断表达式-->
        <where 
        <if test="id!=null">
            id=#{id}
        </if
        </where

where只会去掉第一个多出来的and或者or.拼接后后面可能也会多出and或者or,可以使用trim.

(3)trim自定字符串截取

<trim> prefix="" (前缀:trim标签体中是整个字符串拼接后的结果。
         prefix给拼串后的整个字符串加一个前缀)
          prefixOverrides=" " (前缀覆盖:去掉整个字符串前面多余的字符)
          suffix=" " (后缀:给拼串后的整个字符串加一个后缀)
          suffixOverrides=" " (后缀覆盖:去掉整个字符串后面多余的字符)
 <trim>

2、choose分支选择:

choose (when,otherwise) :分支选择;带了break的swtich-case,如果带了id就用id查,如果带了Name就用Name查;只会进入其中一个

<select id="getEmpsByCondtionChoose" resultType="com.atguigu.mybatis.bean.Employee">
          select * from tbl_employee
          <where>
              <choose>
                <when test="id!=null">
                    id=#{id}
                </when>
                <when test="lastName!=null">
                    last_name like #{lastName}
                </when>
                <otherwise>
                    gender =0
                </otherwise>
              </choose>
          </where>
       </select>

3、set 与if结合的动态更新

set(封装修改条件)

<!--     Set标签的使用
        (假如test类中语句如下
        Employee employee=new Employee(1,"admin",null,null);
        可以去除sql中的多余逗号等)
         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}-->

4、foreach

(1)foreach遍历集合

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

(2)mysql下foreach批量插入的两种方式

批量保存
1、

 <!--public void addEmps(@Param("emps")List<Employee> emps);-->
<!-foreach遍历,mysql支持values(),(),()语法--->
    <insert id="addEmps">
        INSERT into tbl_employee(last_name,email,gender,d_id)
        VALUES  
        <foreach collection="emps" item="emp" separator=",">
            (#{emp.lastName},#{emp.email},#{emp.gender},#{emp.dept.id})
        </foreach>
    </insert>
   <!--test样例:-->
    List<Employee> emps=new ArrayList<>();
           emps.add(new Employee(null,"smith","smith@guigu.com","1",new Department(1)));
           emps.add(new Employee(null,"allen","allen@guigu.com","0",new Department(1)));
           mapper.addEmps(emps);
           openSession.commit();

2、

<!--mysql支持多个sql语句(数据库连接属性,
allowMultiQueries允许使用;分隔多条查寻)
但需要更改配置资源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>

5、内置参数:_parameter&_databaseId

不只是方法传递过来的参数可以被用来判断,取值…
mybatis默认还有两个内置参数:
_parameter:代表整个参数
单个参数:_parameter就是这个参数
多个参数:参数会被封装成一个map;_parameter就代表这个map

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

<!--public List<Employee> getEmpsTestInnerParameter(Employee employee);-->
    <select id="getEmpsTestInnerParameter" resultType="com.atguigu.mybatis.bean.Employee">
        <if test="_databaseId=='mysql'">

         <!--使用多个条件(where)时需要判断传参employee是否为空
         _parameter就代表employee对象
          -->
            select * from tbl_employee
            <if test="_parameter!=null">
                where last_name=#{_parameter.lastName}
            </if>
        </if>

        <if test="_databaseId=='oracle'">
            /*select * from employees*/
        </if>

    </select>

6、_bind_绑定

 <!--public List<Employee> getEmpsTestInnerParameter(Employee employee);-->
    <select id="getEmpsTestInnerParameter" resultType="com.atguigu.mybatis.bean.Employee">
        <!--bind:可以将OGNL表达式的值绑定到一个变量中,方便后来引用这个变量的值-->
        <bind name="_lastName" value="'_'+lastName+'%'"/>
        <if test="_databaseId=='mysql'">

            <!--使用多个条件(where)时需要判断传参employee是否为空-->
            select * from tbl_employee
            <if test="_parameter!=null">
                where last_name like #{_lastName}
            </if>
        </if>

        <if test="_databaseId=='oracle'">
            /*select * from employees*/
        </if>

    </select>

在模糊查询中可以使用bind标签拼接OGNL表达式,但在实际使用中一般在传参时便拼接好了字符串

  EmployeeMapperDynamicSQL mapper = openSession.getMapper(EmployeeMapperDynamicSQL.class);
           Employee employee2=new Employee();
           employee2.setLastName("%e%");
           List<Employee> list = mapper.getEmpsTestInnerParameter(employee2);
           for(Employee employee : list)
           {
               System.out.println(employee);
           }

7、sql标签_抽取可重用的sql片段

 <!--抽取可重用的sql片段
     1、sql抽取:将经常要查询的列名,或者插入用的列名抽取出来方便引用
     2、include标签来引用已经抽取的sql
     3、include还可以自定义一些property,sql标签内部就能使用自定义的属性
             include-property取值的正确方式:${prop},
             #{}(用来取传参的参数)不可以使用
 -->
    <sql id="insertColumn">
        <if test="_databaseId=='mysql'">
            last_name,email,gender,d_id   
        </if>
        <if test="_databaseId=='oracle'">
          <!--last_name,email,gender,d_id-->
        </if>
    </sql>
    
 <insert id="addEmps">
        INSERT into tbl_employee(
        <!--引用外部定义的sql-->
        <include refid="insertColumn">
            <property name="testColomn" value="***"/>
        </include>
        )
        VALUES
        <foreach collection="emps" item="emp" separator=",">
            (#{emp.lastName},#{emp.email},#{emp.gender},#{emp.dept.id})
        </foreach>
    </insert>
    <!--使用自定义的属性来增加要查询的属性名及内容-->
DEBUG 02-08 16:14:46,861 ==>  Preparing: INSERT into tbl_employee( last_name,email,gender,d_id,*** ) VALUES (?,?,?,?) , (?,?,?,?)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值