天天看點

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>
           

上面代碼中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>
           

這裡

<bind>

value

值會使用OGNL計算。

注:對

<bind

參數的調用可以通過

#{}

或 

${}

 方式擷取,

#{}

可以防止注入。

在通用Mapper中支援一種UUID的主鍵,在通用Mapper中的實作就是使用了

<bind>

标簽,這個标簽調用了一個靜态方法,大概方法如下:

<bind name="username_bind" 
      value='@[email protected]().toString().replace("-", "")' />
           
  • 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>
           

這裡注意寫的是

${'%' + name + '%'}

,而不是

%${name}%

,這兩種方式的結果一樣,但是處理過程不一樣。

在MyBatis中處理

${}

的時候,隻是使用OGNL計算這個結果值,然後替換SQL中對應的

${xxx}

,OGNL處理的隻是

${這裡的表達式}

這裡表達式可以是OGNL支援的所有表達式,可以寫的很複雜,可以調用靜态方法傳回值,也可以調用靜态的屬性值。

mybatis中使用ognl的擴充,實作判斷傳入的字段:

xxx.map.xml裡面的用法:

<select id="getAll" parameterType="java.util.Map" resultMap="TaskEntity">
		SELECT task.*,run.subject subject,run.processName processName
		FROM ACT_RU_TASK task left join BPM_PRO_RUN run
		on task.PROC_INST_ID_=run.actInstId
		where 1=1
		<if test="@[email protected](name)"> AND task.name_ LIKE #{name} </if>
		<if test="@[email protected](subject)"> AND run.subject LIKE #{subject} </if>
		<if test="@[email protected](processName)"> AND run.processName LIKE #{processName} </if>
		<if test="@[email protected](orderField)">
			order by task.CREATE_TIME_ desc
		</if>
		<if test="@[email protected](orderField)">
			order by ${orderField} ${orderSeq}
		</if>		
	</select>
           

OGNL.java (Ognl.java 必須放在class目錄,也就是沒有包名)

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

import com.hotent.core.util.BeanUtils;

public class Ognl {
    public Ognl() {
    }

    public static boolean isEmpty(Object o) throws IllegalArgumentException {
        return BeanUtils.isEmpty(o);
    }

    public static boolean isNotEmpty(Object o) {
        return !isEmpty(o);
    }

    public static boolean isNotEmpty(Long o) {
        return !isEmpty(o);
    }

    public static boolean isNumber(Object o) {
        return BeanUtils.isNumber(o);
    }
}
           

參考文檔:MyBatis中的OGNL教程

深入了解MyBatis參數

繼續閱讀