Как генерировать String «элегантно» в Java? - PullRequest
3 голосов
/ 27 апреля 2011

Я хочу сгенерировать строку, такую ​​как команда sql:

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

В настоящее время я использую StringBuilder и некоторую константу String, например "INSERT INTO", чтобы объединить входные параметры String для имени таблицы ивставленные значения.

Однако, помимо проблем с производительностью, эта простая конкатенация выглядит не элегантно.Есть ли другой способ сделать это?

На мой взгляд, подготовленный оператор JDBC является хорошим примером такого "шаблона команды":

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

, тогда вы можете установить имя таблицыи вставленное значение.

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

Тем не менее, я не могу использовать подготовленное утверждение, так как мне нужна только строка ...

И кто-то дает мне подсказку использовать java.util.Regex илиJavaCC для создания строки.Но, насколько я могу судить, что бы ни выбрано для некоторой проблемы элегантности кода, Java String должна быть сгенерирована чем-то вроде StringBuilder, верно ???

Ответы [ 5 ]

13 голосов
/ 27 апреля 2011

Вы можете использовать String.format():

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

Стоит отметить, что любой из этих методов «построения строк» ​​делает вас уязвимыми для атак с использованием SQL-инъекций. Вы должны действительно использовать параметризованные запросы JDBC везде, где это возможно.

Отредактировано для добавления кавычек вокруг строк.

4 голосов
/ 27 апреля 2011

Может быть, вы ищете 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 голосов
/ 27 апреля 2011

Учитывая множество других ответов, и ни один из них не получил вашего одобрения, возможно, вам следует принять тот факт, что фактическая генерация строк (без JPA, PreparedStatement и т. Д.) Будет довольно неэффективной, и создайте служебный класс со статическими генераторами SQL.

edit Показаны примеры того, как я поступил бы, если бы ранее существовавший класс, такой как 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Струнное поколение в душе.Вы также можете использовать это, чтобы «гарантировать», что все ваши вставки защищены от таких атак, как SQL-инъекция.

2 голосов
/ 27 апреля 2011

Вы пробовали просто использовать '+'?

String sql = "INSERT INTO " + table
           +" VALUES(" + value1 + ", " + value2 + ", " = value3+")";
0 голосов
/ 28 апреля 2011

Использовать 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());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...