bind標簽可以使用OGNL表達式創建一個變量並將其綁定到上下文中。
在前面的UserMapper.xml有一個selectByUser方法,這個方法用到了like查詢條件。
使用concat函數連接字符串,在MySQL中,這個函數支持多個參數,但在Oracle中支持兩個參數。由於不同數據庫之間的語法差異,如果更換數據庫,有些SQL語句可能就需要重寫。針對這種情況,可以使用bind標簽來避免由於更換數據庫帶來的一些麻煩
bind標簽的兩個屬性都是必選項,name為綁定到上下文的變量名,value為OGNL表達式。創建一個bind標簽的變量后,就可以在下面直接使用,使用bind拼接字符串不僅可以避免因更換數據庫而修改SQL,也能防止SQL注入。
多數據庫支持:
bind標簽並不能解決更換數據庫帶來的所有問題,那么還可以通過什么方式支持不同的數據庫?這需要用到if標簽以及由MyBatis提供的databaseIdProvider數據庫廠商標識配置。
這里的DB_VENDOR會通過DatabaseMetaData#getDatabaseProductName()返回的字符串進行設置。由於通常情況下這個字符串都非常長而且相同的產品的不同版本會返回不同的值,所以通常通過設置屬性別名來使其變短,代碼如下:
上面列舉了常見的數據庫產品名稱,在有property配置時,databaseId將被設置為第一個能匹配數據庫產品名稱的屬性鍵對應的值,如果沒有匹配的屬性則會被設置為null。如果getDatabaseProductName()返回Microsoft SQL Server,databaseId將被設置為sqlserver。
當基於不同數據庫運行時,MyBatis會根據配置找到合適的SQL去執行。
數據庫的更換可能只會引起某個SQL語句的部分不同,可以使用if標簽配合默認的上下文中的_databaseId參數這種寫法去實現。這樣可以避免大量重復的SQL出現,方便修改。
首先需要在application.properties配置下數據庫標識:(本人使用的是mysql,其它的替換就行)
然后selectByUser方法可以修改如下:
1 <select id="selectByUser" resultType="com.beilin.menber.entity.SysUser"> 2 select<include refid="userBase"/> 3 from 4 sys_user 5 <where> 6 <if test="userName != null and userName !=''"> 7 <if test="_databaseId =='mysql'"> 8 and user_name like concat('%',#{userName},'%') 9 </if> 10 <if test="_databaseId == 'oracle'"> 11 and user_name like '%'||#{userName}||'%' 12 </if> 13 </if> 14 <if test="userEmail != null and userEmail != ''"> 15 and user_email like concat('%',#{userEmail},'%') 16 </if> 17 </where> 18 </select>
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
調用類的靜態字段值
PS:因作者能力有限,如有誤還請諒解