java - 在 Java 中构建具有可变列数的PreparedStatement,用于将数据插入数据库

标签 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不为空,如果不为空,则根据数据库所需的已知数据类型运行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 个可选字段,这段代码也很大。

最佳答案

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

关于java - 在 Java 中构建具有可变列数的PreparedStatement,用于将数据插入数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47820124/

相关文章:

Java Web Start 间歇性 JAR 不更新

java - 从现有项目创建父 Maven 项目

java - EntityNotFoundException 当记录存在时,在更改表之后

MySQL 存储过程中的准备更新语句

java - 多个功能是 logback 标记的良好用例吗?

mysql - 我无法使这个 MySQL 过程像我想要的那样工作(语法错误)

php - 通过Mysql数据库显示信息

php - 将 MYSQL 中存储为 VARCHAR 的日期转换为 MYSQL 兼容日期

java - 执行 SELECT 查询时,PreparedStatement 和 ResultSet 出现问题?

PHP PreparedStatements 字段名称