如何在Java中“优雅地”生成String?

时间:2011-04-27 11:50:49

标签: java string templates

我想生成一个字符串,例如sql command:

   "INSERT INTO xxx VALUES(XXX, XXX, XXX)"

目前我使用StringBuilder和一些String常量,如“INSERT INTO”来连接表名和插入值的输入字符串参数。

然而,除了性能问题之外,这种简单的连接看起来并不优雅。 还有其他方法吗?

在我看来,JDBC准备好的声明是这种“命令模板”的一个很好的例子:

PreparedStatement pstmt=connection.createPreparedStatement("INSERT INTO ? VALUES(?,?,?)");

然后您可以设置表名和插入值。

pstmt.setString(1,"tableA");
pstmt.setInt(2, 100);
...

但是,我不能使用预准备语句,因为我想要的只是String ...

有人给我一些提示,使用java.util.Regex或JavaCC来生成String。 但据我所知,无论为某些代码优点问题选择什么,Java String必须由类似StringBuilder的东西生成,对吧???

5 个答案:

答案 0 :(得分:13)

您可以使用String.format()

String.format("insert into %s values('%s', '%s', '%s')", "user", "user123", "pass123", "yellow");

值得注意的是,任何这些“字符串构建”技术都会让您容易受到SQL注入攻击。您应该尽可能使用JDBC参数化查询。

编辑在字符串周围添加引号。

答案 1 :(得分:4)

也许您正在寻找java.text.MessageFormat

 int planet = 7;
 String event = "a disturbance in the Force";

 String result = MessageFormat.format(
     "At {1,time} on {1,date}, there was {2} on planet {0,number,integer}.",
     planet, new Date(), event);

答案 2 :(得分:2)

您是否尝试过使用'+'?

String sql = "INSERT INTO " + table
           +" VALUES(" + value1 + ", " + value2 + ", " = value3+")";

答案 3 :(得分:2)

鉴于其他答案的多样性,并且没有一个得到你的认可,也许你应该接受实际的字符串生成(没有JPA,PreparedStatement等)将会相当不优雅并使用静态sql生成器创建一个实用程序类

编辑如果预先存在的类(如PreparedStatement)不是一个选项,请展示我如何进行此操作的示例。它不是最优雅的,但它可以实现它的预期(假设我正确输入了所有内容)。

public class SQLUtil {
    public static String generateInsertSQL(String tableName, List<CustomParameter> parmList){
        StringBuilder sb = new Stringbuilder();
        sb.append("insert into ");
        sb.append(tableName);
        sb.append(" values (");
        for (int i = 0; i < parmList.size(); i++){
            customParameter parm = parmList.get(i);
            switch (parm.getType()) { // enum with your desired sql types
                case ParmTypes.String:
                    sb.append("'");
                    sb.append(StringEscapeUtils.escapeSql(String.valueOf(parm.getValue())));
                    sb.append("'");
                    break;
                case ParmTypes.Integer:
                    sb.append(Integer.valueOf(parm.getValue()));
                    break;
            }
            if (i < parmList.size() - 1) sb.append(",");
        }
        sb.append(")");
        return sb.toString();
    }
}

这样,您的业务代码将保持相对优雅,您可以根据自己的内容使用SQL String生成。您还可以使用它来“保证”所有插件都受到保护,以免受SQL注入等攻击。

答案 4 :(得分:0)

使用StringTemplate(http://www.stringtemplate.org/)可能是个不错的选择:

这看起来更好,对吧?

StringTemplate insert = new StringTemplate("INSERT $table$ VALUES ($value; separator=\",\"$)");
insert.setAttribute("table", "aTable");
String[] values = {"1", "1", "'aaa'", "'bbb'"};
for(int i = 0;i < values.length;i++){   
  insert.setAttribute("value", values[i]);  
}
System.out.println(insert.toString());