简体   繁体   English

如何在 Java 中“优雅地”生成字符串?

[英]How to generate String “elegantly” in Java?

I want to generate a string such as sql command:我想生成一个字符串,例如 sql 命令:

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

currently I use StringBuilder and some String constant like "INSERT INTO" to concatenate input String parameters for the table name and inserted values.目前我使用StringBuilder和一些像“INSERT INTO”这样的String常量来连接表名和插入值的输入字符串参数。

However, other than performance issue, this plain concatenation looks not elegant.然而,除了性能问题之外,这种简单的连接看起来并不优雅。 Is there any other way of doing this?有没有其他方法可以做到这一点?

In my opinion, JDBC's prepared statement is one good example of such a "command template":在我看来,JDBC 的prepared statement 就是这种“命令模板”的一个很好的例子:

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

then you can set the table name and inserted value.然后你可以设置表名和插入值。

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

However, I can not use prepared statement, since what I want is just String...但是,我不能使用准备好的语句,因为我想要的只是字符串......

And someone give me some hint to use java.util.Regex or JavaCC to produce the String.有人给我一些提示,让我使用java.util.Regex或 JavaCC 来生成字符串。 But as far as I can see, whatever is chosen for some code elegancy issue, Java String must be generated by something like StringBuilder , right???但据我所知,无论为某些代码优雅问题选择什么, Java String 必须由类似StringBuilder的东西生成,对吧???

You could use String.format() :您可以使用String.format()

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

It's worth noting though, that any of these "string building" techniques leave you vulnerable to SQL injection attacks.不过值得注意的是,任何这些“字符串构建”技术都会使您容易受到 SQL 注入攻击。 You should really use JDBC parameterised queries wherever possible.您应该尽可能使用 JDBC 参数化查询。

Edited to add quotes around strings.编辑为在字符串周围添加引号。

Maybe you are looking for java.text.MessageFormat也许您正在寻找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);

Have you tried just using '+'?您是否尝试过仅使用“+”?

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

Given the variety of other answers and none of them met your approval, perhaps you should accept that the actual String generation (sans JPA, PreparedStatement, etc.) is going to be fairly inelegant and create a utility class with static sql generators. Given the variety of other answers and none of them met your approval, perhaps you should accept that the actual String generation (sans JPA, PreparedStatement, etc.) is going to be fairly inelegant and create a utility class with static sql generators.

edit Showing an example of how I'd go about this if a pre-existing class such as PreparedStatement weren't an option.编辑显示一个示例,说明如果预先存在的 class(例如 PreparedStatement)不是一个选项,我将如何处理 go。 It's not the most elegant, but it does what it's supposed to (assuming I typed it all in correctly).它不是最优雅的,但它做了它应该做的(假设我输入正确)。

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

This way, your business code will remain relatively elegant and you can play around with the SQL String generation to your heart's content.这样,您的业务代码将保持相对优雅,您可以随心所欲地使用 SQL 字符串生成。 You can also use this to "guarantee" all your inserts are protected against such attacks as SQL injection.您还可以使用它来“保证”您的所有插入都受到保护,免受 SQL 注入等攻击。

Use StringTemplate (http://www.stringtemplate.org/) maybe a good choice:使用 StringTemplate (http://www.stringtemplate.org/) 可能是一个不错的选择:

This looks better, right?这看起来更好,对吧?

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM