MyBatis 的动态 SQL 使用 OGNL 表达式

http://commons.apache.org/proper/commons-ognl/language-guide.html

在 XML 中的一些特殊字符需要转义,参考 HTML ISO-8859-1 手册

http://www.w3school.com.cn/tags/html_ref_entities.html

一、IF

https://www.cnblogs.com/jhxxb/p/10637219.html

<select id="selectMyUserByIF" resultType="myUser" parameterType="myUser">
select * from myuser where
<if test="id != null">
id = #{id}
</if>
<if test="name != null &amp;&amp; name != &quot;&quot;">
and name like #{name}
</if>
<if test="age == 0 or age == 1">
and age = #{age}
</if>
</select>

入参没有ID属性时会报错,会拼接成 where and,解决:可以在 where 后添加一个恒成立,如 1=1。或者使用 where 标签,会自动去除 SQL 中多出来的 and 或 or

二、WHERE

<select id="selectMyUserByIF" resultType="myUser" parameterType="myUser">
select * from myuser
<where>
<if test="id != null">
id = #{id}
</if>
<if test="name != null and name != ''.toString()">
and name like #{name}
</if>
<if test="age == 0 or age == 1">
and age = #{age}
</if>
</where>
</select>

where 标签只能去除第一个 and 或 or,所以不能把条件符号写多个或写在后面

三、SET

<update id="updateMyUser" parameterType="myUser">
update myuser
<!-- 用作更新 -->
<set>
<if test="name != null">
name = #{name},
</if>
<if test="age != null">
age = #{age}
</if>
</set>
where id = #{id}
</update>

四、TRIM

<select id="selectMyUserByIF" resultType="myUser" parameterType="myUser">
select * from myuser
<!-- prefix:替换拼接后字符串的前缀,单独使用则为添加。prefixOverrides:想替换的前缀类容(条件),单独使用则为删除
suffix:替换拼接后字符串的后缀,单独使用则为添加。suffixOverrides:想替换的后缀类容(条件),单独使用则为删除 -->
<trim prefix="where" prefixOverrides="AND | OR" suffixOverrides="and">
<if test="id != null">
id = #{id} and
</if>
<if test="name != null and name.trim() != ''">
name like #{name}
</if>
</trim>
</select>

trim 标签可以替代 where 标签

<!-- 等效于 where 标签 -->
<trim prefix="WHERE" prefixOverrides="AND |OR ">
...
</trim>

trim 标签也可以替代 set 标签

<!-- 等效于 set 标签 -->
<trim prefix="set" suffixOverrides=",">
...
</trim>

五、CHOOSE

<select id="selectMyUserByIF" resultType="myUser" parameterType="myUser">
select * from myuser
<where>
<!-- 类似于 if-else if-else 分支结构 -->
<choose>
<when test="id != null">
id = #{id}
</when>
<when test="name != null and name.trim() != ''">
name like #{name}
</when>
<otherwise>
age = 22
</otherwise>
</choose>
</where>
</select>

六、FOREACH

Map 入参

<!--public List<MyUser> selectMyUserByArray(Map<String,Object> maps);-->
<select id="selectMyUserByArray" resultType="myUser">
select * from myuser where id in
<!-- collection:指定要遍历的集合或数组(list 和 array 参数都会特殊处理封装在 Map 中,Map 的 key 默认为 list 或 array)
入参为单个 list 或 array 时 collection 值默认为 list 或 array,若接口方法指定了 @Param 注解,则为 @Param 的值
入参为多个参数可以封装为 Map,collection 值为 Map 中集合或数组对应的 key 的值(Map 的 key 最好为 String 类型)
open:给结果拼接一个前缀
close:给结果拼接一个后缀
item:集合中每一个元素在迭代时的别名,#{item} 取出变量的值,也就是当前遍历出的元素
separator:每个元素之间的分隔符
index:索引
遍历 list 或 arrays 时,index 是当前索引(下标),item 为索引对应的值
遍历 map 时 index 表示 map 的 key,item 为 map 的 value -->
<foreach collection="ids" item="item" index="index" separator="," open="(" close=")">
#{item}
</foreach>
</select>

测试代码

public static void main(String[] args) {
SqlSession session = null;
try {
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
session = sqlSessionFactory.openSession(); MyUserMapper mapper = session.getMapper(MyUserMapper.class);
Map<String,Object> ids = new HashMap<>(10);
ids.put("ids",Arrays.asList(7,8,9,10));
ids.put("b",8);
System.out.println(mapper.selectMyUserByArray(ids));
} catch (IOException e) {
e.printStackTrace();
} finally {
if (session != null) {
session.close();
}
}
}

List 入参

<!--public List<MyUser> selectMyUserByArray(List<Integer> ids);-->
<select id="selectMyUserByArray" resultType="myUser">
select * from myuser where id in
<foreach collection="list" item="item" index="index" separator="," open="(" close=")">
#{item}
</foreach>
</select>

Array 入参

<!--public List<MyUser> selectMyUserByArray(Integer[] ids);-->
<select id="selectMyUserByArray" resultType="myUser">
select * from myuser
<foreach collection="array" item="item" index="index" separator="," open="where id in (" close=",20)">
#{item}
</foreach>
</select>

七、内置参数

<!-- 不只是方法传递过来的参数可以被用来判断和取值,mybatis 默认还有两个内置参数。
_parameter:代表整个参数
单个参数:_parameter 就是这个参数
多个参数:参数会被封装为一个 map,_parameter 就代表这个 map
_databaseId:如果配置了 databaseIdProvider 标签,_databaseId 代表当前数据库的别名 -->
<select id="selectMyUserById" resultType="myUser">
<if test="_databaseId == 'mysql'">
select * from myuser
<if test="_parameter != null">
where id = #{_parameter}
</if>
</if>
<if test="_databaseId == 'oracle'">
select * from oracle_myuser
<if test="_parameter != null">
where name = #{_parameter.name}
</if>
</if>
</select>

八、BIND

<select id="selectMyUserByNameLike" resultType="myUser" parameterType="string">
select * from myuser where name like #{name}
</select>

例 SQL 映射想变为模糊查询有几种方式

1.传入参数时加上 %

2.改用 ${name} 来取值。name 取值会报错,用 _parameter 取值

<select id="selectMyUserByNameLike" resultType="myUser">
select * from myuser where name like '%${_parameter}%'
</select>

3.使用 bind 标签

<select id="selectMyUserByNameLike" resultType="myUser">
<!-- bind:可以将OGNL表达式的值绑定到一个变量中,方便后来引用这个变量的值 -->
<bind name="_name" value="'%'+_parameter+'%'"/>
select * from myuser where name like #{_name}
</select>

九、SQL 复用

<!-- 抽取可重用的sql片段。方便后面引用,使用 include 标签来引用已经抽取的 sql
include 中可以自定义一些 property,sql 标签内部就能使用自定义的属性
include-property:取值用 ${prop}, 使用 #{prop} 不能取出,无法预编译 -->
<sql id="columnNames">
<if test="_databaseId=='mysql'">
${id},name,age
</if>
<if test="_databaseId=='oracle'">
xxx,xxx,xxx
</if>
</sql>
<select id="selectMyUserByNameLike" resultType="myUser" parameterType="string">
select
<include refid="columnNames">
<property name="id" value="id"/>
</include>
from myuser where name like #{name}
</select>

可以使用其他语言来写动态 SQL:MyBatis-Velocity、MyBatis-FreeMarker 和自带的 XML

http://www.mybatis.org/velocity-scripting/

http://www.mybatis.org/freemarker-scripting/

https://www.jianshu.com/p/cecc187410be

MyBatis 动态 SQL 文档

MyBatis-DynamicSQL 动态SQL的更多相关文章

  1. Java-MyBatis:MyBatis 3 动态 SQL

    ylbtech-Java-MyBatis:MyBatis 3 动态 SQL 1.返回顶部 1. 动态 SQL MyBatis 的强大特性之一便是它的动态 SQL.如果你有使用 JDBC 或其它类似框架 ...

  2. MyBatis 示例-动态 SQL

    MyBatis 的动态 SQL 包括以下几种元素: 详细的使用参考官网文档:http://www.mybatis.org/mybatis-3/zh/dynamic-sql.html 本章内容简单描述这 ...

  3. MyBatis的动态SQL详解

    MyBatis的动态SQL是基于OGNL表达式的,它可以帮助我们方便的在SQL语句中实现某些逻辑,本文详解mybatis的动态sql,需要的朋友可以参考下 MyBatis 的一个强大的特性之一通常是它 ...

  4. Mybatis解析动态sql原理分析

    前言 废话不多说,直接进入文章. 我们在使用mybatis的时候,会在xml中编写sql语句. 比如这段动态sql代码: <update id="update" parame ...

  5. mybatis 使用动态SQL

    RoleMapper.java public interface RoleMapper { public void add(Role role); public void update(Role ro ...

  6. MyBatis框架——动态SQL、缓存机制、逆向工程

    MyBatis框架--动态SQL.缓存机制.逆向工程 一.Dynamic SQL 为什么需要动态SQL?有时候需要根据实际传入的参数来动态的拼接SQL语句.最常用的就是:where和if标签 1.参考 ...

  7. 使用Mybatis实现动态SQL(一)

    使用Mybatis实现动态SQL 作者 : Stanley 罗昊 [转载请注明出处和署名,谢谢!] 写在前面:        *本章节适合有Mybatis基础者观看* 前置讲解 我现在写一个查询全部的 ...

  8. MyBatis探究-----动态SQL详解

    1.if标签 接口中方法:public List<Employee> getEmpsByEmpProperties(Employee employee); XML中:where 1=1必不 ...

  9. mybatis中的.xml文件总结——mybatis的动态sql

    resultMap resultType可以指定pojo将查询结果映射为pojo,但需要pojo的属性名和sql查询的列名一致方可映射成功. 如果sql查询字段名和pojo的属性名不一致,可以通过re ...

  10. mybatis.5.动态SQL

    1.动态SQL,解决关联sql字符串的问题,mybatis的动态sql基于OGNL表达式 if语句,在DeptMapper.xml增加如下语句; <select id="selectB ...

随机推荐

  1. SpringBoot整合ssm

    1.创建工程 使用idea可以快速创建SpringBoot的工程 这里选择常用的类库,SpringBoot将各种框架类库都进行了封装,可以减少pom文件中的引用配置: 比如Spring和Mybatis ...

  2. 用牛顿-拉弗森法定义平方根函数(Newton-Raphson method Square Root Python)

    牛顿法(Newton’s method)又称为牛顿-拉弗森法(Newton-Raphson method),是一种近似求解实数方程式的方法.(注:Joseph Raphson在1690年出版的< ...

  3. new 经典基础模板总结

    NOIP-NOI-ZJOI基础模板总结 目录 C++语言和STL库操作 重载运算符操作 /* 重载运算符 格式 如重载小于号 这里是以x递减为第一关键字比较,y递减为第二关键字比较 */ bool o ...

  4. 「浙大ACM」图森未来杯游记一篇以及简易口胡题解

    前言 蒟蒻有参加了ACM比赛,这一次有适合HY和慕容宝宝大佬一起比的,他们好巨啊,把我带飞了. 又是窝掌机,QAQ,他们仗着自己巨,就欺负窝... 我又打了\(4\)个小时的代码,而且那个键盘太恶心了 ...

  5. Dynamic CRM 2015学习笔记(5)CRM 2015 导入 OData Query Designer 解决方案

    以前一直使用OData Query Designer来生成.验证odata查询字符串,本想把它导入到CRM 2015的环境里,但报错: 到MSDN上发现太老版本的solution确实不能再导入到crm ...

  6. stm32使用rt-thread在文件《stm32f1xx_hal.h》中头文件包含顺序引出的错误

    @2019-01-24 [小记] 在学习 rt-thread BSP制作过程中,发现文件<stm32f1xx_hal.h>中 Env工具生成的原始顺序 1. #include " ...

  7. codeforces #541 D. Gourmet choice(拓扑+并查集)

    Mr. Apple, a gourmet, works as editor-in-chief of a gastronomic periodical. He travels around the wo ...

  8. Linux包系列的知识(附:Ubuntu16.04升级到18.04的案例)

    Linux基础:https://www.cnblogs.com/dunitian/p/4822808.html#linux 之前看到朋友还动不动 apt-get update upgrade,就很纳闷 ...

  9. Linux下搜狗输入法和快捷键Ctrl+Space冲突的解决

    配置快捷键(不是搜狗的设置) 把搜狗的启动快捷键给删了(如果有两个键盘[英+中],你按Shift就可以切换了,完全没必要占着茅坑) 其他快捷键冲突在键盘里面设置 over

  10. 编写高质量代码:改善Java程序的151个建议 --[106~117]

    编写高质量代码:改善Java程序的151个建议 --[106~117] 动态代理可以使代理模式更加灵活 interface Subject { // 定义一个方法 public void reques ...