在Mybatis的动态SQL和${}形式的参数中都用到了OGNL表达式。

Mybatis常用的OGNL表达式

e1 or e2:或

<if test="userEmail != null or userEmail == '1'">
</if>

e1 and e2:且

<if test="userEmail != null and userEmail != ''">
</if>

e1 == e2 或e1 eq e2:相等

<if test="userEmail == null and userEmail == ''">
</if>

e1 != e2 或 e1 neq e2:不等

<if test="userEmail != null and userEmail != ''">
</if>

e1 lt e2:小于

<if test="age lt 10">
</if>

e1 lte e2:小于等于

e1 gt e2:大于

e1 gte e2:大于等于

e1 + e2(加),e1 - e2(减),e1 * e2(乘),e1/e2(除),e1%e2(余)

!e或not e:非,取反

e.method(args):调用对象方法

<if test="list != null and list.size() > 0 ">#{userEmail,jdbcType=VARCHAR},
</if>

e.property:对象属性值

<!-- 多接口参数的查询方法(@Param + javaBean方式) --><select id="selectByUserIdAndEnabledUseBean" resultMap="BaseResultMap">select r.id, r.role_name, r.enabled, r.create_by, r.create_time, u.user_name as "user.userName", u.user_email as "user.userEmail"from sys_user u inner join sys_user_role ur on u.id = ur.user_id inner join sys_role r on ur.role_id = r.id where u.id = #{user.id} and r.enabled = #{role.enabled}
</select>

e1[e2]:按索引取值(List、数组和map)

@class@method(args):调用类的静态方法

<bind name="name" value="@ex.mybatis.rbac.mapper.UserMaperTest@setName()"/>

@class@field:调用类的静态字段值

<bind name="name" value="@ex.mybatis.rbac.mapper.UserMaperTest@NAME"/>

MyBatis中什么地方可以使用OGNL

下面这两处地方在MyBatis中处理的时候都是使用OGNL处理的。

动态SQL表达式中

示例1

<select id="xxx" ...>select id,name,... from country<where><if test="name != null and name != ''">name like concat('%', #{name}, '%')</if></where>
</select>

上面代码中test的值会使用OGNL计算结果。

示例2

<select id="xxx" ...>select id,name,... from country<bind name="nameLike" value="'%' + name + '%'"/><where><if test="name != null and name != ''">name like '${nameLike}'</if></where>
</select>

这里的value值会使用OGNL计算。

注:对<bind参数的调用只能通过${}方式获取,如${nameLike}。

在通用Mapper中支持一种UUID的主键,在通用Mapper中的实现就是使用了标签,这个标签调用了一个静态方法,大概方法如下:

<bind name="username_bind" value='@java.util.UUID@randomUUID().toString().replace("-", "")' />

这种方式虽然能自动调用静态方法,但是没法回写对应的属性值,因此使用时需要注意。

${param}参数中

上面like的例子中使用下面这种方式最简单

<select id="xxx" ...>select id,name,... from country<where><if test="name != null and name != ''">name like '${'%' + name + '%'}'</if></where>
</select>

这里注意写的是${‘%’ + name + ‘%’},而不是%${name}%,这两种方式的结果一样,但是处理过程不一样。

在MyBatis中处理${}的时候,只是使用OGNL计算这个结果值,然后替换SQL中对应的${xxx},OGNL处理的只是${这里的表达式}。

这里表达式可以是OGNL支持的所有表达式,可以写的很复杂,可以调用静态方法返回值,也可以调用静态的属性值。

示例1:查询多个父级的所有的子级组织

<select id="selectAllSubDeptByDeptIds" resultType="long">SELECTd.idFROMdept dINNER JOIN(SELECT * FROM ((SELECT @ids :=<!--将集合deptList使用 逗号 拼接起来, 此处使用foreach会查不出结果, 即使是使用了replace去掉了空格的情况下-->'${@org.springframework.util.StringUtils@collectionToCommaDelimitedString(deptIdList)}') a, (SELECT @ids AS _ids ,(SELECT @ids := GROUP_CONCAT(id) FROM dept WHERE FIND_IN_SET(parent_id, @ids)) AS cidsFROMdept dWHERE@ids IS NOT NULL AND d.is_del = 0) b)) T ON FIND_IN_SET(d.id, T.cids)WHEREd.is_del = 0
</select>

示例2:查询未被邀请的组织

<select id="selectNoInvitedDepts" resultType="com.anbao.train.data.dto.dept.DeptTreeDto">SELECTd.id,d.name,d.parent_id,d.hospital_area_idFROMdept dWHEREd.hospital_area_id = #{hospitalAreaId}AND d.merchant_code = #{merchantCode}<if test="deptIds != null and deptIds.size() != 0">AND NOT FIND_IN_SET(d.id,(SELECTgroup_concat( _ids )FROM(( SELECT @ids :='${@org.springframework.util.StringUtils@collectionToCommaDelimitedString(deptIds)}') a,(SELECT@ids AS _ids,(SELECT@ids := GROUP_CONCAT( id )FROMdeptWHEREFIND_IN_SET( parent_id, @ids )) AS cidsFROMdeptWHERE@ids IS NOT NULL) b)))</if>
</select>

示例3:删除多个父级所有的子级组织

<delete id="deleteCourseInvitationSubDepts">DELETEFROMcourse_invitation ciWHEREci.course_id = #{courseId}AND FIND_IN_SET (ci.dept_id,(SELECTgroup_concat( cids )FROM (( SELECT @ids :='${@org.springframework.util.StringUtils@collectionToCommaDelimitedString(deptIdList)}') a,(SELECT@ids AS _ids,(SELECT@ids := GROUP_CONCAT( id )FROMdeptWHEREFIND_IN_SET( parent_id, @ids )) AS cidsFROMdeptWHERE@ids IS NOT NULL) b)))
</delete>

示例4:使用OGNL实现单表的分表功能

分表这个功能是通用Mapper中的新功能,允许在运行的时候指定一个表名,通过指定的表名对表进行操作。这个功能实现就是使用了OGNL。

首先并不是所有的表都需要该功能,因此定义了一个接口,当参数(接口方法只有实体类一个参数)对象继承该接口的时候,就允许使用动态表名。

public interface IDynamicTableName {/*** 获取动态表名 - 只要有返回值,不是null和'',就会用返回值作为表名** @return*/String getDynamicTableName();
}

然后在XML中写表名的时候使用:

<if test="@tk.mybatis.mapper.util.OGNL@isDynamicParameter(_parameter) and dynamicTableName != null and dynamicTableName != ''">${dynamicTableName}
</if>
<if test="@tk.mybatis.mapper.util.OGNL@isNotDynamicParameter(_parameter) or dynamicTableName == null or dynamicTableName == ''">defaultTableName
</if>

由于我需要判断_parameter是否继承了IDynamicTableName接口,简单的写法已经无法实现,所以使用了静态方法,这两个方法如下:

/*** 判断参数是否支持动态表名** @param parameter* @return true支持,false不支持*/
public static boolean isDynamicParameter(Object parameter) {if (parameter != null && parameter instanceof IDynamicTableName) {return true;}return false;
}/*** 判断参数是否b支持动态表名** @param parameter* @return true不支持,false支持*/
public static boolean isNotDynamicParameter(Object parameter) {return !isDynamicParameter(parameter);
}

根据<if>判断的结果来选择使用那个表名。

另外注意XML判断中有一个dynamicTableName,这个参数是根据getDynamicTableName方法得到的,MyBatis使用属性对应的getter方法来获取值,不是根据field来获取值。

Mybatis常用的OGNL表达式相关推荐

  1. 为了熟练掌握动态SQL你必须要知道Mybatis中的OGNL表达式

    前言 OGNL是个什么东西?很多刚入门Java的同学会有点陌生.但是在Structs流行的时代OGNL可是必会的数据渲染技术.它全称Object Graph Navigation Language,作 ...

  2. 你必须要知道Mybatis中的OGNL表达式

    文章目录 前言 Mybatis中的OGNL 条件断言 四则运算赋值 类的内置方法 取值操作 赋值操作 总结 前言 OGNL是个什么东西?很多刚入门Java的同学会有点陌生.但是在Structs流行的时 ...

  3. MyBatis 一个动态sql的问题(动态SQL基于OGNL表达式)<if test=“state == ‘0‘“>单个的字符要使用双引号,改为<if test=‘state == “1“‘>或

    MyBatis 一个动态sql的问题(动态SQL基于OGNL表达式) <if test="state == '0'"> 单个的字符要使用双引号,改为<if tes ...

  4. Mybatis中的OGNL使用总结=

    博客01----Mybatis中的OGNL使用总结=================== 2016年09月07日 23:47:41 dijkstral 阅读数:7362 经常在写mapper中用到一些 ...

  5. ognl表达式的研究

    OGNL -- 完美的催化剂 为了解决数据从View层传递到Controller层时的不匹配性,Struts2采纳了XWork的OGNL方案.并且在OGNL的基础上,构建了 OGNLValueStac ...

  6. mybatis ognl表达式

    MyBatis常用OGNL表达式 e1 or e2 e1 and e2 e1 == e2,e1 eq e2 e1 != e2,e1 neq e2 e1 lt e2:小于 e1 lte e2:小于等于, ...

  7. Mybatis常用标签详解

    文章目录 命名空间 顶级元素 select insert, update 和 delete sql resultMap cache cache-ref 动态sql if标签 choose.when.o ...

  8. struts2教程(9)--OGNL表达式使用

    OGNL表示式使用和值栈 一.介绍 OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目. Struts2框架使用OGNL作为默认的 ...

  9. Struts2框架--学习笔记(下):OGNL表达式、值栈操作、拦截器、struts2标签、文件上传

    一.OGNL概述:OGNL是一种表达式 (1)在struts2中操作值栈数据. (2)一般把ognl在struts2中操作,和struts2标签一起使用操作值栈. (3)ognl不是strut2的一部 ...

  10. OGNL表达式struts2标签“%,#,$”

    http://www.blogjava.net/parable-myth/archive/2010/10/28/336353.html 一.什么是OGNL,有什么特点? OGNL(Object-Gra ...

最新文章

  1. 实力坑队友! CTO 写出低级 Bug,致公司 70 GB 数据遭泄露!
  2. Fabio技术手册(2):部署
  3. 成功解决AttributeError: module tensorflow has no attribute reset_default_graph
  4. python学习(字符串、整数、列表)
  5. ClickHouse 副本协同原理:ReplicatedMergeTree引擎
  6. 算法(二叉树-矩阵-堆排序)
  7. tstringlist怎么查看是否存在该数据_注意!研究生招生信息只公开1个月!应该怎么用?...
  8. Java 实现图片合成
  9. NYOJ242 - 计算球体积
  10. maven tomcat eclipse 配置 debug
  11. 设计模式(六)建造者(创建型)
  12. 关于socket的简单的客户服务端编程
  13. 智力与联系能力的关系
  14. 使用神经网络(Keras)完成对土壤的湿度估计
  15. linux wifi音箱,基于Orangpi Zero和Linux ALSA实现WIFI无线音箱(三)
  16. Spring.NET学习笔记18——整合NHibernate(基础篇) Level 300
  17. vue中全局注册和局部注册
  18. 魅族16th完美开启Usb调试模式的经验
  19. EXCEL--如何做多选对话框
  20. 大数据查询分析引擎比较

热门文章

  1. 大连计算机类书店小结
  2. HTML5期末大作业:关于旅游主题网站设计——开心网旅游网页源码(15页) HTML+CSS+JavaScript
  3. VOD崛起《暮光之城》带动电影同步发行模式
  4. Foobar音乐播放器——最佳音乐播放器 - imsoft.cnblogs
  5. Java移位运算符原来这么简单
  6. 分享100个好看且实用的JavaScript特效
  7. Javascript 特效大全
  8. Unix编程艺术-翻译-开篇
  9. 两道CTF Reverse题目(windows平台)
  10. 关于rtx 2009 远程控制插件 下载的问题