MyBatis中OGNL

来源:互联网 发布:代尔夫特理工大学 知乎 编辑:程序博客网 时间:2024/06/08 14:48

MyBatis中的OGNL教程

有些人可能不知道MyBatis中使用了OGNL,有些人知道用到了OGNL却不知道在MyBatis中如何使用,本文就是讲如何在MyBatis中使用OGNL。

如果我们搜索OGNL相关的内容,通常的结果都是和Struts有关的,你肯定搜不到和MyBatis有关的,虽然和Struts中的用法类似但是换种方式理解起来就有难度。

MyBatis常用OGNL表达式

  • e1 or e2
  • e1 and e2
  • e1 == e2,e1 eq e2
  • e1 != e2,e1 neq e2
  • e1 lt e2:小于
  • e1 lte e2:小于等于,其他gt(大于),gte(大于等于)
  • e1 in e2
  • e1 not in e2
  • e1 + e2,e1 * e2,e1/e2,e1 - e2,e1%e2
  • !e,not e:非,求反
  • e.method(args)调用对象方法
  • e.property对象属性值
  • e1[ e2 ]按索引取值,List,数组和Map
  • @class@method(args)调用类的静态方法
  • @class@field调用类的静态字段值

上述内容只是合适在MyBatis中使用的OGNL表达式,完整的表达式点击这里。

MyBatis中什么地方可以使用OGNL?

如果你看过深入了解MyBatis参数,也许会有印象,因为这篇博客中提到了OGNL和一些特殊用法。

如果没看过,建议找时间看看,上面这篇博客不是很容易理解,但是理解后会很有用。

MyBatis中可以使用OGNL的地方有两处:

  • 动态SQL表达式中
  • ${param}参数中

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

下面通过举例来说明这两种情况的用法。

1.动态SQL表达式中

例一,MySQL like 查询:

<select id="xxx" ...>    select id,name,... from country    <where>        <if test="name != null and name != ''">            name like concat('%', #{name}, '%')        </if>    </where></select>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

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

例二,通用 like 查询:

<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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

这里<bind>value值会使用OGNL计算。

注:对<bind参数的调用可以通过#{}或 ${} 方式获取,#{}可以防止注入。

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

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

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

2.${param}参数中

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

<select id="xxx" ...>    select id,name,... from country    <where>        <if test="name != null and name != ''">            name like '${'%' + name + '%'}'        </if>    </where></select>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

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

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

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

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

上面说的是OGNL简单的使用方法。这里举个OGNL实现数据库分表的例子。

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

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

public interface IDynamicTableName {    /**     * 获取动态表名 - 只要有返回值,不是null和'',就会用返回值作为表名     *     * @return     */    String getDynamicTableName();}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

然后在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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

由于我需要判断_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);}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

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

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

最后

如果你真想了解MyBatis中的OGNL用法,自己多写几个例子测试玩玩,动手测试是一种好的学习方式。

转载自:http://blog.csdn.net/isea533/article/details/50061705

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 退休时无派遣证怎么办 档案里没有派遣证怎么办 档案中派遣证丢失怎么办 中专毕业后想读大学该怎么办 软考准考证丢了怎么办 面试薪资要低了怎么办 应聘等通知没有电话回复怎么办 学生信息表里的籍贯不对怎么办? 小学生信息表里的籍贯不对怎么办? 钉钉下班没打卡怎么办 如果在厂里饭卡丢了怎么办 工作上做错了事想辞职怎么办 结婚辞职怀孕感觉做错了怎么办 换新手机了钉钉怎么办 公众号申请链接无效怎么办 指纹打卡机时间调错已打卡怎么办 智慧云平台先锋讲座打不开怎么办 下雨穿套裙工装好冷怎么办 国家债务违约不要国际融资怎么办 欠钱的确还不起怎么办 生完孩孑后手发账握不死手怎么办 工作调动没啥消息怎么办 裁剪刀老是推歪怎么办 衣服上粘胶水了怎么办 衣服钻掉了有胶怎么办 衣服上贴纸掉了怎么办 裤子沾上502胶水怎么办 衣服上沾泡沫胶怎么办 衣服上面滴上502怎么办 502胶水弄衣服上怎么办 裤子上粘了胶怎么办 胶水滴在衣服上怎么办 衣服上有502胶水怎么办 衣服上面粘了胶怎么办 衣服上的胶干了怎么办 凌晨4点到火车站怎么办 运管罚款没钱交怎么办 郑州地铁票没买怎么办 遇到吸毒者拦路威胁要钱怎么办 开车遇见拦路要钱的怎么办 高速上有人拦车怎么办