每个 XML Node 会解析成对应的 SQL Node 对象。
public interface SqlNode { //将各Sql片段合并到DynamicContext中,拼接称为完整的SQL boolean apply(DynamicContext context); } apply方法会根据传入的参数context,参数解析该SqlNode所记录的SQL片段,并调用DynamicContext.appendSql()方法将解析后的SQL片段追加到DynamicContext.的sqlBuilder中保存。当SQL节点下的所有SqlNode完成解析后,可以通过DynamicContext.getSql()获取一条完成的SQL语句。最简单的SqlNode,功能仅仅就是将自身记录的text拼接到context上下文中。
//StaticTextSqlNode public boolean apply(DynamicContext context) { context.appendSql(text); return true; }if标签平常用的最多,在处理对应节点逻辑时,其主要工作就是通过Ognl表达式和传入的参数进行判断,看传入的参数值是否有满足if test里的表达式,满足将SQL片段合并到context上下文中。若不满足test则过滤掉这一部分SQL片段,不添加到context中。
<where /> 标签的 SqlNode 实现类,继承至WhereSqlNode。 <set /> 标签的 SqlNode 实现类,继承至SetSqlNode。
WhereSqlNode会传入prefix=WHERE和prefixesToOverride=["AND ","OR ","AND\n", "OR\n", "AND\r", "OR\r", "AND\t", "OR\t"]SetSqlNode会传入prefix=WHERE和prefixesToOverride=[“,”]所以说trim和where、set是同一个套路<trim /> 标签的 SqlNode 实现类
private final String prefix; private final String suffix; /** * 需要被删除的前缀 */ private final List<String> prefixesToOverride; /** * 需要删除的后缀 */ private final List<String> suffixesToOverride;<foreach /> 标签的 SqlNode 实现类
<bind /> 标签的 SqlNode 实现类,只要通过
public boolean apply(DynamicContext context) { //NOTE: OGNL表达式 final Object value = OgnlCache.getValue(expression, context.getBindings()); //NOTE: 绑定到上下文(记录到ContextMap中) context.bind(name, value); return true; }