【mybatis】动态sql

来源:互联网 发布:党章党规网络测试答案 编辑:程序博客网 时间:2024/05/22 03:11

    MyBatis 的强大特性之一便是它的动态 SQL。以前开发时候,拼接sql的时候要确保不能忘了必要的空格,还要注意省掉列名列表最后的逗号,非常麻烦。但是Mybatis动态SQ,对sql语句进行灵活操作,通过表达式进行判断,可以实现对sql灵活的拼接、组装。


一、if+where


通过if和where,通过传入不同的参数,就可以对传入的参数做判空,然后根据传入的参数查询。

slqMappper.xml如下:

 <!--  测试动态sql第一版-->   <select id="TestGeneralSql" parameterType="com.dmsdbj.itoo.teachingManagement.entity.TrainingProgramsEntity" resultType="int">     SELECT COUNT(*) FROM t_training_programs  <where>          <if test="id!=null and id !=''" >               and id =#{id}          </if>          <if test="remark!=null and remark!=''">                AND remark=#{remark}          </if>          <if test="operator!=null and operator!=''">              AND  operator =#{operator}          </if>  </where>   </select>


if标签可以在很多类型的sql语句中,如果只使用if标签,如果拼接的第一个条件为null,直接拼接第二个条件,会导致sql语句中多出来一个ANd,导致报错。这个时候,我们可以使用whre动态语句来解决。这个“where”标签会知道如果它包含的标签中有返回值好的话,它就插入一个“where”,此外,如果标签返回内容为And 或OR开头的,则它会删除掉。

测试代码如下:

@Testpublic void TestGeneralSql( ){TrainingProgramsEntity t = new TrainingProgramsEntity();//t.setId("00114F8E7C50DB05F72B26");t.setRemark("test");t.setOperator("栗振娟"); int count= trainingProgramsFacade.TestGeneralSql(t); System.out.println("========="+count);}
只传入operator字段,就会只拼接operator查询条件,执行效果如下:


传入id,remark,operator三个参数,拼接三个查询条件,执行拼接sql如下:

传入remark,operator两个参数,执行拼接sql如下:


二、if+update语句


原来sql写法:

UPDATE   t_training_programs SET course_id ='2', operator='2', profession_id='2'  WHERE   id='1'

    当update语句中,没有使用if标签时,如果有一个参数为null,都会导致错误。

    当在update语句中使用if标签时,如果前面的if没有执行,就会导致逗号多余错误,使用set标签可以将动态的配置set标签关键字,并且踢出追加到 末尾的不相关的逗号。

如果set包含的内容为空的话,则会出错。

使用if+set标签修改后,如果传入的参数为空,那么不进行更新,保持数据库原值。

<update id="TestGeneralSql" parameterType="com.dmsdbj.itoo.teachingManagement.entity.TrainingProgramsEntity">  UPDATE   t_training_programs          <set>                <if test="courseId!=null ">                    course_id =#{courseId},                </if>                  <if test="operator!=null">                      operator=#{operator},                  </if>                  <if test="professionId!=null">                      profession_id=#{professionId},                  </if>          </set>     WHERE    id=#{id}    </update>

三、sql片段


sql片段,可以将判断等公共的代码片段抽取出来,组成一个sql片段。其他的sql语句,就可以引用sql片段,方便程序员开发,达到代码复用的效果。


1.定义sql片段

<!--定义多种查询条件的sql片段-->    <sql id="query_trainingPrograms_where">        <!-- 基于单表来定义,这样可靠性才高。并且在sql片段中不要包含where-->        <if test="id!=null and id !=''" >             and id =#{id}         </if>         <if test="remark!=null and remark!=''">             AND remark=#{remark}         </if>        <if test="operator!=null and operator!=''">            AND  operator =#{operator}        </if>           </sql>      </mapper>

2.引用sql片段
<!--添加sql片段之后的动态sql,第二版-->   <!--引用sql片段,如果refid指定的id不在本mapper文件中,需要在前边添加上namespace-->    <select id="TestGeneralSql" parameterType="com.dmsdbj.itoo.teachingManagement.entity.TrainingProgramsEntity" resultType="int">        SELECT COUNT(*) FROM t_training_programs        <where>         <include  refid="query_trainingPrograms_where"/>        </where>    </select>

四、foreach循环


向sql传递数组或者list,mybatis使用foreach来解析。循环的对象当然主要是java容器和数组。链接:Mybatis实例之foreach

colleaction 指定输入的对象集合的属性。

item表示集合中每一个元素进行迭代时的别名,
index指 定一个名字,用于表示在迭代过程中,每次迭代到的位置,
open表示该语句以什么开始,
separator表示在每次进行迭代之间以什么符号作为分隔 符,
close表示以什么结束。


1.测试代码

@Testpublic void TestGeneralSql( ){TrainingProgramsEntity t = new TrainingProgramsEntity();//传入多个idList<String> ids= new ArrayList<String>();ids.add("00114F8E7C50DB05F72B26");ids.add("0014499D38BA5AA746DB1F");ids.add("002A40BA9ABCE6F41A375F");t.setIds(ids); int count= trainingProgramsFacade.TestGeneralSql(t); System.out.println("========="+count);}

2.or语句查询

-- 查询包含三个id的sql语句,用OR语句SELECT * FROM t_training_programs WHERE id='00114F8E7C50DB05F72B26' OR id='0014499D38BA5AA746DB1F' or id='002A40BA9ABCE6F41A375F'

<foreach collection="ids" item="T_id" open="AND ("  close=")" separator="or">         <!-- 每个遍历需要拼接的串-->          id=#{T_id}      </foreach>




3.IN语句查询

-- 查询包含三个id的sql语句,用in语句SELECT * FROM t_training_programs  WHERE id in('00114F8E7C50DB05F72B26','0014499D38BA5AA746DB1F','002A40BA9ABCE6F41A375F')


<foreach collection="ids" item="t_id" open="and id In(" close=")" separator=",">           #{t_id}      </foreach>




五、choose  when otherwise


    choose标签时按照顺序其内部when标签的test条件是否成立的。如果有一个成立,那么choose结束。当choose中所有when的条件都不满足时,则执行otherwise中的sql。类似于Java中的switch语句,choose为switch,when为case,otherwise则为default。

如下面的例子,我写了两个限制条件,choose会从上到下选择一个when标签的test为true的sql执行。为了安全考虑,我们使用where将choose包裹起来。

  <!--动态sql,choose when otherwirse语句-->   <!-- choose判断参数。--><select id="TestGeneralSql" parameterType="com.dmsdbj.itoo.teachingManagement.entity.TrainingProgramsEntity" resultType="int">   SELECT COUNT(*) FROM t_training_programs  <where>   <choose>       <when test="operator!=null">            operator LIKE #{operator}       </when>        <when  test="remark!=null">         AND  remark  LIKE #{remark}        </when>       <otherwise>       </otherwise>   </choose>  </where></select>

六.trim标记


trim是一个格式化的标记,可以完成set或者where标记的功能。

如下代码:

将foreach的开始串和结束串,直接放在trim中,同样可以实现遍历效果。

       <!-- prefix :前缀 suffix:后缀-->          <trim  prefix="AND (" suffix=")">           <foreach collection="ids" item="T_id"  separator="or">               <!-- 每个遍历需要拼接的串-->          id=#{T_id}      </foreach>          </trim>

参考例子:mybatis动态sql中的trim标签的使用


小结:

初步了解,还需要在实战中不断熟悉和深入对比。



原创粉丝点击