Сборка PreparedStatement в Java с переменным числом столбцов для вставки данных в базу данных [дубликаты]

0

Какая хорошая схема проектирования для достижения этого без бесконечного кода?

Учитывая сценарий, при котором пользователь может вводить 1... 100 столбцов, возможно, 23 один раз, 32 на другой вкладке и 99 полей на другой вставке и т.д. Все они могут быть разными полями каждый раз.

PreparedStatement в Java должен знать, какие column names следует вводить первым, сколько ? для ввода значений в запрос INSERT типы данных имен полей базы данных для обеспечения правильного setInt и setString т.д.

Для менее чем около 10 столбцов вы можете обойти эту проблему со следующей логикой;

1) Если variableEnteredForFieldName не является нулевым, добавьте его в соответствующие части запроса в форме установки типа строкового типа;

fieldName_1

?

2) Сделайте то же самое для всех введенных имен полей

3) Измените конечный трейлинг , который, естественно, будет присутствовать как в field names и в ? s

4) Создайте PreparedStatement

5) Повторите те же параметры ввода снова, чтобы определить значение переменнойEnteredForFieldName не равно null, если не null, затем запустите setInt или setString на основе известного типа данных, который требуется базе данных, и установите это для правильного номера индекса для?,

До тех пор, пока логика построителя запросов и логика заливки запроса имеют имена/значения в правильном порядке в частях 1 и 2, все работает хорошо. Тем не менее, это означает дублирование всего кода, который относится к этой логике, один для генерации SQL для использования при создании PreparedStatement, а другой для заполнения PreparedStatement.

Это можно использовать для небольшого количества входных параметров, но это скоро становится неуправляемым для большего количества входных параметров.

Есть ли лучший дизайн для достижения той же логики?

Нижеприведенный код представляет собой схему всего вышеперечисленного для справки;

String fieldName1 = request.getParameter("fieldName1");
    String fieldName2 = request.getParameter("fieldName2");

    //Build Query
    String fieldNames = "";
    String fieldQuestionMarks = "";

    if (fieldName1 != null) {
        fieldNames = fieldNames + " FIELD_NAME_1 ,";
        fieldQuestionMarks = fieldQuestionMarks + " ? ,";
    }

    if (fieldName2 != null) {
        fieldNames = fieldNames + " FIELD_NAME_2 ,";
        fieldQuestionMarks = fieldQuestionMarks + " ? ,";
    }

//Trim the trailing ,
    fieldNames = fieldNames.substring(1, fieldNames.length() - 1);
    fieldQuestionMarks = fieldQuestionMarks.substring(1, fieldQuestionMarks.length() - 1);


    try {
        String completeCreateQuery = "INSERT INTO TABLE_NAME ( " + fieldNames + " ) VALUES ( " + fieldQuestionMarks + " );";
        Connection con = DriverManager.getConnection(connectionURL, user, password);
        PreparedStatement preparedStatement = con.prepareStatement(completeCreateQuery);

        int parameterIndex = 1;

        //Fill Query
        if (fieldName1 != null) {
            preparedStatement.setString(parameterIndex, fieldName1);
            parameterIndex++;
        }

        if (fieldName2 != null) {
            preparedStatement.setInt(parameterIndex, Integer.parseInt(fieldName2));
            parameterIndex++;
        }
    }

Как вы можете видеть, он умеет. Но даже с двумя необязательными полями этот код огромен.

Теги:
prepared-statement

1 ответ

0
Лучший ответ

Как я вижу это, если пользователь может опустить любой из столбцов из списка, то все столбцы являются необязательными и могут быть безопасно установлены в NULL во время вставки. Таким образом, все, что вам нужно, это одно подготовленное выражение с "монстром" INSERT, причем все столбцы перечислены; то во время фактической операции вставки вы выполняете петлю, используя предоставленные пользователем данные, устанавливая значения для предоставленных столбцов и вызываете setNull() для опущенных столбцов. Вам нужно будет поддерживать структуру где-нибудь (скорее всего, ваш класс DAO), сопоставляя имена столбцов с их порядком в инструкции SQL.

  • 0
    @ Джим Гаррисон: объясни, пожалуйста, отрицательный голос. На мой взгляд, ни один из связанных вопросов фактически не предлагал жизнеспособного решения (серьезно, динамически созданный список INSERT?), И при этом мое предложение не предлагалось там.
  • 0
    Я также удивился, почему за этот ответ так быстро проголосовали. Для меня это идеальное решение, которое вы предоставили Алексу. Для этого я могу просто создать указанную инструкцию INSERT monster, и если данные для этого параметра не были введены пользователем, я могу просто использовать опцию setNull (), которую вы упомянули. Я не знал об этой функции. Благодарю.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню