Mybatis常用的OGNL表达式
在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表达式相关推荐
- 为了熟练掌握动态SQL你必须要知道Mybatis中的OGNL表达式
前言 OGNL是个什么东西?很多刚入门Java的同学会有点陌生.但是在Structs流行的时代OGNL可是必会的数据渲染技术.它全称Object Graph Navigation Language,作 ...
- 你必须要知道Mybatis中的OGNL表达式
文章目录 前言 Mybatis中的OGNL 条件断言 四则运算赋值 类的内置方法 取值操作 赋值操作 总结 前言 OGNL是个什么东西?很多刚入门Java的同学会有点陌生.但是在Structs流行的时 ...
- MyBatis 一个动态sql的问题(动态SQL基于OGNL表达式)<if test=“state == ‘0‘“>单个的字符要使用双引号,改为<if test=‘state == “1“‘>或
MyBatis 一个动态sql的问题(动态SQL基于OGNL表达式) <if test="state == '0'"> 单个的字符要使用双引号,改为<if tes ...
- Mybatis中的OGNL使用总结=
博客01----Mybatis中的OGNL使用总结=================== 2016年09月07日 23:47:41 dijkstral 阅读数:7362 经常在写mapper中用到一些 ...
- ognl表达式的研究
OGNL -- 完美的催化剂 为了解决数据从View层传递到Controller层时的不匹配性,Struts2采纳了XWork的OGNL方案.并且在OGNL的基础上,构建了 OGNLValueStac ...
- 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:小于等于, ...
- Mybatis常用标签详解
文章目录 命名空间 顶级元素 select insert, update 和 delete sql resultMap cache cache-ref 动态sql if标签 choose.when.o ...
- struts2教程(9)--OGNL表达式使用
OGNL表示式使用和值栈 一.介绍 OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目. Struts2框架使用OGNL作为默认的 ...
- Struts2框架--学习笔记(下):OGNL表达式、值栈操作、拦截器、struts2标签、文件上传
一.OGNL概述:OGNL是一种表达式 (1)在struts2中操作值栈数据. (2)一般把ognl在struts2中操作,和struts2标签一起使用操作值栈. (3)ognl不是strut2的一部 ...
- OGNL表达式struts2标签“%,#,$”
http://www.blogjava.net/parable-myth/archive/2010/10/28/336353.html 一.什么是OGNL,有什么特点? OGNL(Object-Gra ...
最新文章
- post和get的区别?
- 视频分解图片原理;图片合成视频原理
- Virtual DOM的简单实现
- 广播模块加继电器怎么接线_变频器如何与PLC相连接,怎么用PLC控制?
- 实施Exchange 2013中的 MailTip
- 广西计算机学业水平考试,2017年6月广西信息技术学业水平考试(1)-2017广西信息技术会考真题...
- 【转】ASP.NET内幕 - IIS处理模型
- ElasticSearch倒排索引
- bzoj 1133: [POI2009]Kon(DP)
- 从直男审美到时尚达人,这群阿里工程师要让服饰行业换个玩法!
- zabbix部署及监控测试
- STL库:string
- 在 Win10 系统下安装 JDK 及配置环境变量的方法
- 计算机中流水线的应用,计算机中的流水线技术
- mysql - user/privileges/用户与权限/用户权限/管理用户权限
- 一文搞定Diff算法
- 怎么学好计算机专业?
- java实现第三届蓝桥杯DNA对比
- mvn -deploy 报错 Failed to deploy artifacts: Could not transfer artifact
- 卡诺图在程序中的应用