策略模式的应用之 MyBatis GenericTokenParser
推荐阅读:策略模式
GenericTokenParser 使用
MyBatis 中有一个 GenericTokenParser 类,它用于解析字符串中的占位符:
public class GenericTokenParser {
private final String openToken;
private final String closeToken;
private final TokenHandler handler;
public GenericTokenParser(String openToken, String closeToken, TokenHandler handler) {
this.openToken = openToken;
this.closeToken = closeToken;
this.handler = handler;
}
public String parse(String text) {
// ...
builder.append(handler.handleToken(expression.toString()));
// ...
}
}
可以看到它的构造方法接收三个参数,openToken 和 closeToken 分别是占位符开始和结束的标记,而 handler 是一个 TokenHandler 对象。在 parse 方法中,会调用 handler 的 handleToken 方法对占位符进行处理。
下面是一个使用示例:
ParameterMappingTokenHandler handler = new ParameterMappingTokenHandler(configuration, parameterType, additionalParameters);
GenericTokenParser parser = new GenericTokenParser("#{", "}", handler);
String sql = parser.parse(originalSql);
上面的代码能够将 originalSql 中类似于#{userId}这样的占位符替换为?。
GenericTokenParser 的 parse 方法,作用是解析占位符,每遇到一个占位符,其都会调用 TokenHandler 的 handleToken 方法对其进行处理。
处理的结果就是使用 handleToken 方法的返回值替换字符串中对应的占位符。下面会看到,ParameterMappingTokenHandler 的返回值就是一个?。
TokenHandler 接口
TokenHandler 是一个接口,它只有一个 handleToken 方法,用于返回占位符需要被替换为的值:
public interface TokenHandler {
String handleToken(String content);
}
ParameterMappingTokenHandler 是一个实现该接口的类,它的返回值是?:
@Override
public String handleToken(String content) {
parameterMappings.add(buildParameterMapping(content));
return "?";
}
策略模式中有三个部分——策略接口、具体策略、上下文。
在这里,TokenHandler 就是策略接口,ParameterMappingTokenHandler 就是具体的策略,GenericTokenParser 就是上下文。
我们知道,除了#{}占位符,MyBatis 中还有${}占位符。${}参数占位符的解析是在 TextSqlNode 类的 apply() 方法中完成的:
@Override
public boolean apply(DynamicContext context) {
GenericTokenParser parser = createParser(new BindingTokenParser(context, injectionFilter));
context.appendSql(parser.parse(text));
return true;
}
private GenericTokenParser createParser(TokenHandler handler) {
return new GenericTokenParser("${", "}", handler);
}
可以看到 BindingTokenParser 是 TokenHandler 实现类,其和 ParameterMappingTokenHandler 一样也是具体的策略,作用是将占位符替换为 Mapper 参数值。
浙公网安备 33010602011771号