mybatis动态sql详解

mybatis动态sql详解,第1张

前言

大家对mybaTIs执行任意sql语句都了解,那么MyBaTIs执行动态SQL语句呢?下面小编给大家解答下mybaTIs执行动态sql语句的方法,感兴趣的朋友参考下吧

大家基本上都知道如何使用 MyBaTIs 执行任意 SQL,使用方法很简单,例如在一个 XXMapper.xml 中:

你可以如下调用:

sqlSession.selectList(“executeSql”, “select * from sysuser where enabled = 1”);

或者你可以在 XXMapper.java 接口中定义如下方法:

List executeSql(String sql);

然后使用接口调用方法:

1xxMapper.executeSql(“select * from sysuser where enabled = 1”);

上面这些内容可能都会,下面在此基础上再复杂一点。

假如像上面SQL中的enabled = 1我想使用参数方式传值,也就是写成 enabled = #{enabled},如果你没有遇到过类似这种需求,可能不明白为什么要这么写,举个例子,要实现一种动态查询,可以在前台通过配置 SQL,提供一些查询条件就能实现一个查询的功能(为了安全,这些配置肯定是开发或者实施做的,不可能让用户直接 *** 作数据库)。

针对这个功能,使用 MyBatis 实现起来相当容易。配置 SQL 肯定要执行,用上面讲的这种方式肯定可以执行 SQL,如何提供参数呢?参数就是enabled = #{enabled}中的#{enabled}部分。如果再多一些条件,一个配置好的 SQL 如下:

select * from sysuser

where enabled = #{enabled}

and userName like concat(‘%’,#{userName},‘%’)

这种情况下,该怎么用 MyBatis 实现呢?

首先 XML 中修改如下:

接口中的方法修改为:

List executeSql(Map map);

然后调用方法:

Map map = new HashMap();//这里的 sql 对应 XML 中的 ${sql}map.put(“sql”, “select * from sysuser ”+ “ where enabled = #{enabled} ”+ “ and userName like concat(‘%’,#{userName},‘%’)”);//#{enabled}map.put(“enabled”, 1);//#{userName}map.put(“userName”, “admin”);//接口方式调用List list = xxMapper.executeSql(map);//sqlSession方式调用sqlSession.selectList(“executeSql”, map);

有了这个SQL之后,就可以将 enabled 和 userName 作为条件提供给用户。这两个条件显然是必填的。如果是可选的,那该怎么写?

也许有人想到了是不是可以用 MyBatis 中的动态 SQL,使用标签等等?

再回答这个问题前,我们先看处理动态 SQL 的 DynamicSqlSource 中的代码:

@Override

public BoundSql getBoundSql(Object parameterObject) {

DynamicContext context = new DynamicContext(configuration, parameterObject);

rootSqlNode.apply(context);

SqlSourceBuilder sqlSourceParser = new SqlSourceBuilder(configuration);

Class < ?>parameterType =

parameterObject == null ? Object.class: parameterObject.getClass();

SqlSource sqlSource = sqlSourceParser.parse(context.getSql(),

parameterType, context.getBindings());

BoundSql boundSql = sqlSource.getBoundSql(parameterObject);

for (Map.Entry < String, Object > entry: context.getBindings().entrySet()) {boundSql.setAdditionalParameter(entry.getKey(), entry.getValue());}

return boundSql;

}

MyBatis 处理动态 SQL 时,所有动态 SQL 的标签都会处理为 SqlNode (这里的rootSqlNode)对象,包含${}的也会处理为 TextSqlNode 对象,在上面方法的前两行,就是 MyBatis 处理动态 SQL 的地方。

因此如果我们在${sql} 中的内容包含嵌套的${}和等标签时,他们在 MyBatis 解析 XML 为 SqlNode 对象时,XML