开发者

A tool resembling spring's NamedParameterUtils for regular strings processing?

开发者 https://www.devze.com 2023-03-11 04:15 出处:网络
I would like to replace named parameters in a string with values, like when using Python\'s % operator.

I would like to replace named parameters in a string with values, like when using Python's % operator. Spring supports something very similar to the functionality I need with NamedParameterUtils, but for some reason it's tightly coupled to Jdbc and replacing those named-parameters with question marks.

So, if I want to do ":a is :b" % {"a":"Java", "b":"Beautiful"} must I resort to using some heavy artillery like Velocity?开发者_开发百科 or am I missing something simple?

Update: used Dmitry's code to write my own simple version:

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();
}


It should take about 50 lines of code to write what you want.

Here's an excerpt from a "TrivialTemplate" I wrote a while back, which does something very similar:

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);
    }
}

I'm using BeanUtils to support arbitrary data objects, but you can just as easily limit it to Maps.

0

精彩评论

暂无评论...
验证码 换一张
取 消