我想用值替换字符串中的命名参数,就像使用Python的%运算符一样。Spring支持与我使用NamedParameterUtils所需的功能非常相似的功能,但出于某种原因,它与Jdbc紧密耦合,并用问号替换那些命名参数。
所以,如果我想做":a is :b" % {"a":"Java", "b":"Beautiful"}
,我必须使用像Velocity这样的重炮吗?还是我错过了一些简单的东西?
更新:使用Dmitry的代码编写我自己的简单版本:
public static String formatSqlWithNamedParams(String sqlTemplate, Map<String, Object> params){
StringWriter writer = new StringWriter();
Pattern var = Pattern.compile("\$\{\s*([\w\[\]\(\)\.]+)\s*\}");
Matcher match = var.matcher(sqlTemplate);
int offset = 0;
while (match.find()) {
writer.write(sqlTemplate.substring(offset, match.start()));
String key = match.group(1);
Object val = params.get(key);
writer.write(val.toString());
offset = match.end();
}
writer.write(sqlTemplate.substring(offset));
return writer.toString();
}
编写所需内容大约需要50行代码。
这是我不久前写的一个"TrivialTemplate"的摘录,它的作用非常相似:
private final Pattern var = Pattern
.compile("\{\s*([\w\[\]\(\)\.]+)\s*\}");
private final PropertyUtilsBean bean = new PropertyUtilsBean();
private final Object data;
public TrivialTemplate(Object data) {
this.data = data;
}
public void process(BufferedReader reader, PrintWriter writer) {
String line = null;
try {
while ((line = reader.readLine()) != null) {
Matcher match = var.matcher(line);
int offset = 0;
while (match.find()) {
writer.write(line.substring(offset, match.start()));
String key = match.group(1);
if (!isBlank(key)) {
Object val = bean.getNestedProperty(data, key
.toLowerCase());
writer.write(val != null ? val.toString() : "{null}");
} else {
writer.write("{null}");
}
offset = match.end();
}
writer.write(line.substring(offset));
writer.println();
}
} catch (Throwable t) {
throw new RuntimeException("template error", t);
}
}
我使用BeanUtils来支持任意数据对象,但您可以很容易地将其限制为"贴图"。