Mybatis动态Sql
2018-07-11 20:19:35
  • 0
  • 0
  • 0
  • 0

动态SQL支持:

if

choose (when, otherwise)

trim (where, set)

foreach

if

动态 SQL 通常要做的事情是根据条件包含 where 子句的一部分。比如:

<select id="findActive" resultType="Blog"> 对应到Mapper接口中的同名方法上

SELECT * FROM BLOG WHERE state = ‘ACTIVE’

<if test="title != null"> test属性中是一个OGNL逻辑表达式,如果返回结果为true则执行标签体,否则不执行标签体

AND title like #{title} 参数中的title属性如果不为空,则 SELECT * FROM BLOG WHERE state = ‘ACTIVE’ and AND title like #{title}

</if>

</select>

test属性中的OGNL表达式可以是多个逻辑判断组成的,例如

<if test="author != null and author.name != null">

AND author_name like #{author.name}

</if>

insertSelective定义中有很多的if判断,根据对应的属性生成不同的SQL语句

动态插入获取的优势是default设置生效

updateByPrimaryKeySelective同样处理

choose, when, otherwise可以实现开关分支判断

<select id="findActiveBlogLike" resultType="Blog">

SELECT * FROM BLOG WHERE state = ‘ACTIVE’

<choose>这个标签体中只要一个条件判断成立,则立即退出标签.可以使用这个标签模拟出if/else结构

<when test="title != null">AND title like #{title}</when>

<when test="author != null and author.name != null">如果上面的判读成立,执行标签体后立即退出choose结构;只有不成立时才会判断这个条件

AND author_name like #{author.name}

</when>

<otherwise>AND featured = 1</otherwise>当多有的when不成立时执行这个标签体

</choose>

</select>

注意:其中的语法格式为元素类型为 "choose" 的内容必须匹配 "(when*,otherwise?)"

where用于生成对应的where关键字

<select id="selectCondition" parameterType="map" resultType="UserBean">

select * from t_users where 1=1

<if test="username!=null">

and username=#{username}

</if>

<if test="password!=null">

and password=#{password}

</if>

<if test="birth!=null">

and birth=#{birth}

</if>

</select>

<where>标签体中没有生成任何查询条件,则不会生成where关键字;如果生成了SQL语句,同时SQL语句以and/or开头,则自动剔除多余的and/or关键字

<select id="selectCondition" parameterType="map" resultType="UserBean">

select * from t_users

<where>

<if test="username!=null">

and username=#{username}

</if>

<if test="password!=null">

and password=#{password}

</if>

<if test="birth!=null">

and birth=#{birth}

</if>

</where>

</select>

set和where类似,用于生成update语句中的set关键字,如果标签体为空,则不会生成set关键;如果标签体不为空,则会自动剔除所生成SQL语句末尾的多余的逗号

<update id="updateByPrimaryKeySelective" parameterType="com.yan.entity.User">

update t_users

<set>

<if test="username != null">

username = #{username,jdbcType=VARCHAR},

</if>

<if test="password != null">

password = #{password,jdbcType=VARCHAR},

</if>

</set>

where id = #{id,jdbcType=BIGINT}

</update>

trim和where/set类似

<trim prefix="WHERE自动添加的标签体生成的SQL语句的前缀" prefixOverrides="AND |OR 需要自动剔除的SQL语句的前缀,不会区分大小写"

suffix=",,,,自动添加的后缀" suffixOverrides=",自动去除的后缀"

>

...

</trim>

替代<where>

<trim prefix="where" prefixOverrides="AND | OR">

<if test="username!=null">

and username=#{username}

</if>

<if test="password!=null">

and password=#{password}

</if>

</trim>

替代<set>

<trim prefix="set" suffixOverrides=",">

<if test="username != null">

username = #{username,jdbcType=VARCHAR},

</if>

<if test="password != null">

password = #{password,jdbcType=VARCHAR},

</if>

</trim>

foreach

对一个集合进行遍历,通常是在构建 IN 条件语句的时候

<if test="ids!=null">

and id in

<foreach collection="ids在map中的集合值的key,这是一个OGNL表达式,用于按照key从map中获取对应的集合"

index="kk序号,从0开始" item="pp循环控制变量,每次迭代访问一个元素,就会临时赋值给它" open="(生成内容的开头,只添加一次"

close=")生成内容的结束,只添加一次" separator=",每个元素之间的分隔符,末尾处不会添加">

${pp}

</foreach>

</if>

你可以将任何可迭代对象(如 List、Set 等)、Map 对象或者数组对象传递给 foreach 作为集合参数。当使用可迭代对象或者数组时,index 是当前迭代的

次数,item 的值是本次迭代获取的元素。当使用 Map 对象(或者 Map.Entry 对象的集合)时,index 是键,item 是值

bind

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

<select id="selectBlogsLike" resultType="Blog">

<bind name="pattern可以理解为变量名" value="'%' + _parameter.getTitle() + '%'对应的值" />

SELECT * FROM BLOG WHERE title LIKE #{pattern通过名称引用上面指定的值value}

</select>

sql

这个元素可以被用来定义可重用的 SQL 代码段,可以包含在其他语句中。它可以被静态地(在加载参数) 参数化. 不同的属性值通过包含的实例变化

<sql id="userColumns"> ${alias}.id,${alias}.username,${alias}.password </sql>

如果那个SQL需要使用 ${alias}.id,${alias}.username,${alias}.password内容,可以直接通过

<include refid="userColumns">引用上面<sql>块中定义的内容

<property name="alias" value="t1"/>用于给sql块中的${alias}进行赋值

</include>,

进行引用,并支持给${alias}变量进行赋值

<sql id="Base_Column_List">

id, username, password, birth, sex, salary

</sql>

如果使用select *执行查询,效率很低,执行查询之前需要访问数据字典获取所有的列名。在开发中不建议;

  select <include refid="Base_Column_List"/> from t_users

 
最新文章
相关阅读