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


    前言

    OGNL是个什么东西?很多刚入门Java的同学会有点陌生。但是在Structs流行的时代OGNL可是必会的数据渲染技术。它全称Object Graph Navigation Language,作用是降低对数据层访问的难度,它拥有类型转换、访问对象方法、操作集合对象等功能。目前已经很少通过OGNL来访问数据层了,写这篇文章主要是因为目前国内大部分的ORM框架是Mybatis,而Mybatis中的动态SQL技术运用了OGNL。

    Mybatis中的OGNL

    不少人在Mybatis的Mapper文件中写过这样的判断:

    <if test="field!= null and field!=''">
      and some_col = #{field}
    if>
    
    • 1
    • 2
    • 3

    field不为null并且不为空字符的情况下增加一个查询条件。其中 test就是一个OGNL表达式。Mybatis中的OGNL表达式主要有两种用途。

    条件断言

    这种是我们最常用的。执行动态SQL的条件断言,常用的有这些表达式:

    • b1 or b2 条件 或
    • b1 and b2 条件 与
    • !b1 取反,也可以写作not b1
    • b1 == b2,b1 eq b2 判断两个值相等
    • b1 != b2,b1 neq b2 判断两个值不相等
    • b1 lt b2 判断b1小于(less than)b2
    • b1 gt b2 判断b1大于(greater than)b2
    • b1 lte b2:判断b1小于等于b2
    • b1 gte b2:判断b1大于等于b2
    • b1 in b2 判断b2包含b1
    • b1 not in b2 判断b2不包含b1

    这些表达式经常和test配合。

    四则运算赋值

    还有一些表达式用来赋值或者增强属性。经常用来做模糊搜索的 bind标签:

    <bind name="nameLike" value="'%'+ name + '%'"/>
    
    • 1

    这里的value也属于OGNL表达式 e1+e2,字符串是拼接,数字的话就是加法运算,我们可以引申出肯定还有:

    • e1*e2 乘法
    • e1/e2 除法
    • e1-e2 减法
    • e1%e2 取模

    类的内置方法

    其实Mybatis的Mapper.xml中还可以使用对象的内置方法,比如我们需要判断一个java.util.Collection集合是否为空,可以这么写:

    <if test="collection!=null and collection.size()> 0">
      and some_col = #{some_val}
    if>
    
    • 1
    • 2
    • 3

    这里就使用了对象的内置方法Collection.size()。
    我们还可以调用自定义对象CollectionUtils的静态方法来判断集合是否为空:

    package cn.felord.util;
    
    public final class CollectionUtils {
    	public static boolean isNotEmpty(Collection<?> collection) {
    		return (collection != null && !collection.isEmpty());
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    那么上面的判断改为:

    <if test="@cn.felord.util.CollectionUtils@isNotEmpty(collection)">
      and some_col = #{some_val}
    if>
    
    • 1
    • 2
    • 3

    不要忘了这里要带上类的全限定名。

    取值操作

    取值操作的话,如果是对象直接e.property,如果是集合或者Map可以e[index|key],通过索引或者键名来取值。分别举个例子:

    # 对象取属性
    user.username
    # 集合取元素
    array[1] 
    # map 取值
    map['username']
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    其实静态属性也能取值调用,跟上面的静态方法类似:

    @cn.felord.Cache@user
    
    • 1

    对应Java代码:

    package cn.felord;
    
    public final class Cache {
     public static User user = new User ("felord.cn") ;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    赋值操作

    上面的取值除了可以做判断还可以用来SQL参数赋值:

         <where>
             
                 username = #{username}
             
                 and user_id =${userId}
             
                 and id = ${user.id}
             
                 and age = ${@@abs(-12345678)}
             
                 and gender =${@cn.felord.GenderEnum@MALE.ordinal()}
                 and id=${@cn.felord.Cache@user.userId}
         where>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    通过${}符号可以用OGNL表达式给SQL参数赋值,还有一些OGNL的 玩法可以去看官方文档。

    总结

    今天对Mybatis中的OGNL表达式进行了总结和分组,对常用的和不常用的用法进行了归纳,希望能够帮助你掌握Mybatis动态SQL的深度运用。不过请尽量将复杂的操作简单化,不要写过于复杂的OGNL表达式,无论是从性能上还是并发安全上都是很重要的因素。

  • 相关阅读:
    在Mission Planner上校准外置GPS罗盘
    学习rsync
    PCL点云处理之配准中的匹配对连线可视化显示 Correspondences(二百一十九)
    PHP将数组导出为CSV文件
    创建型模式之原型模式
    mac安装jdk
    点燃市场热情,让产品风靡全球——实用推广策略大揭秘!
    精讲stable diffusion的controlNet插件
    Android渲染系列之原理概述篇
    深入理解JavaScript中的事件冒泡与事件捕获
  • 原文地址:https://blog.csdn.net/weixin_38898423/article/details/127839838