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:因作者能力有限,如有误还请谅解