MyBatis官方文档
动态 SQL
bind bind 元素可以从 OGNL 表达式中创建一个变量并将其绑定到上下文。比如:
< select id = " selectBlogsLike" resultType = " Blog" >
< bind name = " pattern" value = " ' %' + _parameter.getTitle() + ' %' " />
SELECT * FROM BLOG
WHERE title LIKE #{pattern}
</ select>
多数据库支持 一个配置了“_databaseId”变量的 databaseIdProvider 可用于动态代码中,这样就可以根据不同的数据库厂商构建特定的语句。比如下面的例子:
< insert id = " insert" >
< selectKey keyProperty = " id" resultType = " int" order = " BEFORE" >
< if test = " _databaseId == ' oracle' " >
select seq_users.nextval from dual
</ if>
< if test = " _databaseId == ' db2' " >
select nextval for seq_users from sysibm.sysdummy1"
</ if>
</ selectKey>
insert into users values (#{id}, #{name})
</ insert>
源码
package org. apache. ibatis. scripting. xmltags;
import java. util. HashMap;
import java. util. Map;
import ognl. OgnlContext;
import ognl. OgnlException;
import ognl. OgnlRuntime;
import ognl. PropertyAccessor;
import org. apache. ibatis. reflection. MetaObject;
import org. apache. ibatis. session. Configuration;
public class DynamicContext {
public static final String PARAMETER_OBJECT_KEY = "_parameter" ;
public static final String DATABASE_ID_KEY = "_databaseId" ;
static {
OgnlRuntime. setPropertyAccessor ( ContextMap. class , new ContextAccessor ( ) ) ;
}
private final ContextMap bindings;
private final StringBuilder sqlBuilder = new StringBuilder ( ) ;
private int uniqueNumber = 0 ;
public DynamicContext ( Configuration configuration, Object parameterObject) {
if ( parameterObject != null && ! ( parameterObject instanceof Map ) ) {
MetaObject metaObject = configuration. newMetaObject ( parameterObject) ;
bindings = new ContextMap ( metaObject) ;
} else {
bindings = new ContextMap ( null) ;
}
bindings. put ( PARAMETER_OBJECT_KEY, parameterObject) ;
bindings. put ( DATABASE_ID_KEY, configuration. getDatabaseId ( ) ) ;
}
public Map< String, Object> getBindings ( ) {
return bindings;
}
public void bind ( String name, Object value) {
bindings. put ( name, value) ;
}
public void appendSql ( String sql) {
sqlBuilder. append ( sql) ;
sqlBuilder. append ( " " ) ;
}
public String getSql ( ) {
return sqlBuilder. toString ( ) . trim ( ) ;
}
public int getUniqueNumber ( ) {
return uniqueNumber++ ;
}
static class ContextMap extends HashMap < String, Object> {
private static final long serialVersionUID = 2977601501966151582 L;
private MetaObject parameterMetaObject;
public ContextMap ( MetaObject parameterMetaObject) {
this . parameterMetaObject = parameterMetaObject;
}
@Override
public Object get ( Object key) {
String strKey = ( String) key;
if ( super . containsKey ( strKey) ) {
return super . get ( strKey) ;
}
if ( parameterMetaObject != null) {
return parameterMetaObject. getValue ( strKey) ;
}
return null;
}
}
static class ContextAccessor implements PropertyAccessor {
@Override
public Object getProperty ( Map context, Object target, Object name)
throws OgnlException {
Map map = ( Map) target;
Object result = map. get ( name) ;
if ( map. containsKey ( name) || result != null) {
return result;
}
Object parameterObject = map. get ( PARAMETER_OBJECT_KEY) ;
if ( parameterObject instanceof Map ) {
return ( ( Map) parameterObject) . get ( name) ;
}
return null;
}
@Override
public void setProperty ( Map context, Object target, Object name, Object value)
throws OgnlException {
Map< Object, Object> map = ( Map< Object, Object> ) target;
map. put ( name, value) ;
}
@Override
public String getSourceAccessor ( OgnlContext arg0, Object arg1, Object arg2) {
return null;
}
@Override
public String getSourceSetter ( OgnlContext arg0, Object arg1, Object arg2) {
return null;
}
}
}