使用可变数量的列在Java中构建PreparedStatement以将数据插入数据库

时间:2017-12-14 18:42:41

标签: java mysql prepared-statement

如果没有无尽的代码,实现这一目标的好设计模式是什么?

考虑到用户可以输入1 ... 100列,可能23次,另一次插入32次,另一次插入等99个字段的情况。所有这些都可能每次都是不同的字段。

Java中的PreparedStatement需要知道首先要输入的column names,要放入?查询的值部分中的INSERT,数据库的数据类型字段名称以确保输入正确的setIntsetString等。

如果不到10列左右,您可以通过以下逻辑来解决这一挑战;

1)如果variableEnteredForFieldName不为null,则以“字符串”构建器类型设置的形式附加到查询的相关部分;

fieldName_1

?

2)对所有输入的字段名称执行相同操作

3)删除,field names中自然存在的最终尾随?

4)创建PreparedStatement

5)再次运行相同的输入参数以确定variableEnteredForFieldName不为null,如果不为null,则根据数据库所需的已知数据类型运行setInt或setString,并将其设置为正确的索引号。这个?

只要查询构建器逻辑和查询填充逻辑在第1部分和第2部分中具有正确顺序的名称/值,那么一切正常。但它确实意味着复制与此逻辑相关的整个代码,一个用于生成在创建PreparedStatement时使用的SQL,另一个用于填充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++;
        }
    }

正如你所看到的,它是可行的。但即使只有2个可选字段,这段代码也很庞大。

1 个答案:

答案 0 :(得分:0)

我看到它的方式,如果用户能够省略列表中的任何列,那么所有列都是可选的,并且可以在插入期间安全地设置为NULL。因此,你所需要的只是一个准备好的声明与"怪物" INSERT,列出所有列;然后在实际的插入操作期间,循环访问用户提供的数据,设置所提供列的值,并为省略的列调用setNull()。您需要在某处(最可能是您的DAO类)维护一个结构,将列名映射到它们在SQL语句中的顺序。