在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. post和get的区别?
  2. 视频分解图片原理;图片合成视频原理
  3. Virtual DOM的简单实现
  4. 广播模块加继电器怎么接线_变频器如何与PLC相连接,怎么用PLC控制?
  5. 实施Exchange 2013中的 MailTip
  6. 广西计算机学业水平考试,2017年6月广西信息技术学业水平考试(1)-2017广西信息技术会考真题...
  7. 【转】ASP.NET内幕 - IIS处理模型
  8. ElasticSearch倒排索引
  9. bzoj 1133: [POI2009]Kon(DP)
  10. 从直男审美到时尚达人,这群阿里工程师要让服饰行业换个玩法!
  11. zabbix部署及监控测试
  12. STL库:string
  13. 在 Win10 系统下安装 JDK 及配置环境变量的方法
  14. 计算机中流水线的应用,计算机中的流水线技术
  15. mysql - user/privileges/用户与权限/用户权限/管理用户权限
  16. 一文搞定Diff算法
  17. 怎么学好计算机专业?
  18. java实现第三届蓝桥杯DNA对比
  19. mvn -deploy 报错 Failed to deploy artifacts: Could not transfer artifact
  20. 卡诺图在程序中的应用

热门文章

  1. 单片机原理及应用实验报告
  2. 《黑客X档案2007配套光盘》2007年上半年合集(6期)
  3. 【EJB基础】开发一个简单的EJB应用程序
  4. Bigemap中添加离线地图数据包 教程
  5. 硬笔书法教学:看了都舍不得擦掉的粉笔字,网友纷纷夸赞“行走的打印机”
  6. SQL Server触发器简单例子
  7. QQ空间的汉字转拼音代码
  8. ECharts地图省会,城市,县坐标
  9. Trace View
  10. Java正则表达式语法与示例