MyBatis动态SQL————MyBatis动态SQL标签的用法

1.MyBatis动态SQL

MyBatis 的强大特性之一便是它的动态 SQL,即拼接SQL字符串。如果你有使用 JDBC 或其他类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句有多么痛苦。拼接的时候要确保不能忘了必要的空格,还要注意省掉列名列表最后的逗号。利用动态 SQL 这一特性可以彻底摆脱这种痛苦。

通常使用动态 SQL 不可能是独立的一部分,MyBatis 当然使用一种强大的动态 SQL 语言来改进这种情形,这种语言可以被用在任意的 SQL 映射语句中。

动态 SQL 元素和使用 JSTL 或其他类似基于 XML 的文本处理器相似。在 MyBatis 之前的版本中,有很多的元素需要来了解。MyBatis 3 大大提升了它们,现在用不到原先一半的元素就可以了。MyBatis 采用功能强大的基于 OGNL 的表达式来消除其他元素。

2.动态SQL标签:if,choose (when, otherwise),trim (where, set),foreach

2.1  if标签:直接上代码

<select id="queryByIdAndTitle"
     resultType="Blog">
  SELECT * FROM BLOG
  WHERE 1=1
  <if test="id!= null and title!=null">
    AND id=#{id} and title=#{title}
  </if>
</select>

注:if标签一般用于非空验证,如上例,若id为空,if标签里的代码,将不会执行,反之,则会执行。

2.2  choose(when,otherwise)标签:直接上代码

<select id="queryBy"
     resultType="Blog">
  SELECT * FROM BLOG WHERE 1=1
  <choose>
    <when test="title != null">
      AND title like #{title}
    </when>
    <otherwise>
      AND id= 1
    </otherwise>
  </choose>
</select>

注:choose(when,otherwise)标签相当于switch(case,default) ,如上例,若title 为空,when标签里的代码,将不会执行,默认执行otherwise标签里面的代码。

2.3  trim(where,set)标签:直接上代码

<select id="queryBy" resultType="com.scme.pojo.User" parameterType="com.scme.pojo.User">
                 select * from user
                 <where>
                         <if test="username!=null and password!=null">
                             and username=#{username} and password=#{password}
                         </if>
                 </where>
</select>

注:假设上例传入的username,password不为空,代码就可以运行成功!但朋友们可能有疑问了,实际上执行的sql语句是什么呢?其实,sql为:select * from user

where username=? and password=?  朋友们是否发现,where标签代替了sql中where关键字,但if中的and不见了。其实where标签可以自动去除是“AND”或“OR”开头的sql中的“AND”或“OR”关键字。

如果 where 元素没有按正常套路出牌,我们还是可以通过自定义 trim 元素来定制sql,实现where标签的效果。代码如下:

<select id="queryBy" resultType="com.scme.pojo.User" parameterType="com.scme.pojo.User">
                 select * from user
                 <trim prefix="WHERE" prefixOverrides="AND |OR ">
                          <if test="username!=null and password!=null">
                             and username=#{username} and password=#{password}
                         </if>
                </trim>
                 <!-- 效果同上          <where>
                         <if test="username!=null and password!=null">
                             and username=#{username} and password=#{password}
                         </if>
                 </where> -->
         </select>

set标签,代码如下:

<update id="updateUser" parameterType="com.scme.pojo.User">
                 update user
                 <set>
                     <if test="username!=null">
                             username=#{username}
                     </if>
                 </set>
                 <where>
                     <if test="id!=null">
                             id=#{id}
                     </if>
                 </where>
         </update>

注:set标签功能和where标签差不多,set标签代替了sql中set关键字,set标签可以自动去除sql中的多余的“,”

同理,trim标签也可以实现set标签的功能

<update id="updateUser" parameterType="com.scme.pojo.User">
                 update user 
         <trim prefix="set" prefixOverrides=",">
              <if test="username!=null"> username=#{username} </if>         </trim>           <where>                 <if test="id!=null"> id=#{id} </if>                   </where>

</update>

2.4  foreach标签:foreach标签实现批量删除,直接上代码

<delete id="batchDelete" parameterType="java.lang.String">
  delete from user
  where id in
  <foreach item="id" index="index" collection="list"
      open="(" separator="," close=")">
        #{id}
  </foreach>
</delete >

注:foreach标签可迭代任何对象(如列表、集合等)和任何的字典或者数组对象传递给foreach作为集合参数,当使用可迭代对象或者数组时,index是当前迭代的次数,item的值是本次迭代获取的元素。当使用字典(或者Map.Entry对象的集合)时,index是键,item是值。collection标签可以填(‘list‘,‘array‘,‘map‘)。

foreach元素的属性主要有 item,index,collection,open,separator,close。

item表示集合中每一个元素进行迭代时的别名;

index指 定一个名字,用于表示在迭代过程中,每次迭代到的位置;

open表示该语句以什么开始,

separator表示在每次进行迭代之间以什么符号作为分隔符;

close表示以什么结束。

3.bind

bind 元素可以从 OGNL 表达式中创建一个变量并将其绑定到上下文。比如:

<select id="selectBlogsLike" resultType="Blog">
  <bind name="pattern" value="‘%‘ + _parameter.getTitle() + ‘%‘" />
  SELECT * FROM BLOG
  WHERE title LIKE #{pattern}
</select>

4.Multi-db vendor support

一个配置了“_databaseId”变量的 databaseIdProvider 对于动态代码来说是可用的,这样就可以根据不同的数据库厂商构建特定的语句。比如下面的例子:

<insert id="insert">
  <selectKey keyProperty="id" resultType="int" order="BEFORE">
    <if test="_databaseId == ‘oracle‘">
      select seq_users.nextval from dual
    </if>
    <if test="_databaseId == ‘db2‘">
      select nextval for seq_users from sysibm.sysdummy1"
    </if>
  </selectKey>
  insert into users values (#{id}, #{name})
</insert>
动态 SQL 中可插拔的脚本语言

MyBatis 从 3.2 开始支持可插拔的脚本语言,因此你可以在插入一种语言的驱动(language driver)之后来写基于这种语言的动态 SQL 查询。

可以通过实现下面接口的方式来插入一种语言:

public interface LanguageDriver {
  ParameterHandler createParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql);
  SqlSource createSqlSource(Configuration configuration, XNode script, Class<?> parameterType);
  SqlSource createSqlSource(Configuration configuration, String script, Class<?> parameterType);
}

一旦有了自定义的语言驱动,你就可以在 mybatis-config.xml 文件中将它设置为默认语言:

<typeAliases>
  <typeAlias type="org.sample.MyLanguageDriver" alias="myLanguage"/>
</typeAliases>
<settings>
  <setting name="defaultScriptingLanguage" value="myLanguage"/>
</settings>

除了设置默认语言,你也可以针对特殊的语句指定特定语言,这可以通过如下的 lang 属性来完成:

<select id="selectBlog" lang="myLanguage">
  SELECT * FROM BLOG
</select>

或者在你正在使用的映射中加上注解 @Lang 来完成:

public interface Mapper {
  @Lang(MyLanguageDriver.class)
  @Select("SELECT * FROM BLOG")
  List<Blog> selectBlog();

注意 可以将 Apache Velocity 作为动态语言来使用,更多细节请参考 MyBatis-Velocity 项目。

如有帮助,请关注!

时间: 2024-10-08 08:02:14

MyBatis动态SQL————MyBatis动态SQL标签的用法的相关文章

MyBatis动态SQL之一使用 if 标签和 choose标签

bootstrap react https://segmentfault.com/a/1190000010383464 xml 中 < 转义 to thi tha <if test="pricehigh!=null"> and price < #{pricehigh,jdbcType=INTEGER} </if> MyBatis动态SQL之一使用 if 标签和 choose标签 <select id="getItems" p

MyBatis学习总结_11_MyBatis动态Sql语句

MyBatis中对数据库的操作,有时要带一些条件,因此动态SQL语句非常有必要,下面就主要来讲讲几个常用的动态SQL语句的语法 MyBatis中用于实现动态SQL的元素主要有: if choose(when,otherwise) trim where set foreach 1.if 对属性进行判断,如果不为空则执行判断条件 [html] view plaincopy <select id="selectByCriteria" parameterType="com.mu

MyBatis学习总结(六)——动态SQL

MyBatis的动态SQL是基于OGNL表达式的,它可以帮助我们方便的在SQL语句中实现某些逻辑. MyBatis中用于实现动态SQL的元素主要有: if choose(when,otherwise) foreach where set trim 下面我们主要说 where set trim 这三个标签 1,where标签 <!-- 查询学生list,like姓名,=性别 --> <select id="getStudentListWhere" parameterTy

Mybatis 使用Mapper接口的Sql动态代码方式进行CURD和分页查询

1.Maven的pom.xml 2.配置文件 2.1.db.properties 2.2.mybatis.xml 2.3.log4j.xml 3.MybatisUtil工具类 4.Mapper映射文件 1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http

【MyBatis学习07】动态sql

1. 动态sql 动态sql是mybatis中的一个核心,什么是动态sql?动态sql即对sql语句进行灵活操作,通过表达式进行判断,对sql进行灵活拼接.组装.就拿上一篇博文中对用户的综合查询一例来说: select * from user where user.sex = #{user.sex} and user.username like '%${user.username}%' 假如这个user是null咋整?或者user.sex或者user.username为null呢?所以更严谨的做

mybatis入门篇3 ---- 动态sql,缓存,以及分页jar包的使用

首先我们来看一下动态sql,动态sql就是传递的参数不确定的时候,使用if,where,select,choose,set等标签,先来看一下 lib,rescources,以及utils里面文件不变,直接来看使用 直接看if跟where,if使用比较简单,就是if会有一个条件判断,如果条件满足,就会把if里面的sql语句块加入slq语句,where就是帮助我们加载一个where条件判断,并且会把拼接语句中的第一个and删除掉,接下来看一下例子 看一下UserMapper public inter

Mybatis映射原理,动态SQL,log4j

1.理清mybatis中的#和$之间的区别? #{ }:表示一个预处理参数,参数类型不定,是根据传入的参数类型来设定的. 类似于JDBC中的? 特例使用,模糊查询:(针对oracle): and username like concat(concat('%',#{username}),'%') 采取的$的方式传入参数,所有采取$的方式传入的参数都只是字符串(无论传入的是什么,都会当成字符串处理),潜在的危险就是SQL注入的问题. and username like '%${value}%' 注意

MyBatis 源码分析——动态SQL语句

有几年开发经验的程序员应该都有暗骂过原生的SQL语句吧.因为他们不能一句就搞定一个业务,往往还要通过代码来拼接相关的SQL语句.相信大家会理解SQL里面的永真(1=1),永假(1=2)的意义吧.所以mybatis动态SQL功能在笔者看来是最引吸人的.为了更好的区别XML映射文件上的SQL语句.mybatis把SQL语句分为四类.那么这个笔者已经在前面的章节里面讲过了.但是我们在开发过程中常常用到的也就俩种:静态和动态. 关于静态和动态的定义,笔者是这样子理解的--静态SQL语句显示就是里面没有相

MyBatis 之 使用五 动态SQL

MyBatis 提供使用 ognl 表达式动态生成 SQL的功能. 1. if 2. where where 可以自动处理掉第一个拼接条件里的 and <!-- 动态 sql 查询用户信息 -->   <select id="findUserByDynamicSql" parameterType="user" resultType="user">    select * from users    <!-- wher