什么是一个好的设计模式来实现这一点而无需无尽的代码?
假设用户可以输入 1...100 列,一次可能输入 23 列,另一次插入可能输入 32 列,另一次插入可能输入 99 个字段,等等。所有这些字段每次也可能是不同的字段。
Java中的PreparedStatement需要知道什么column names
先输入多少?
放入 INSERT
的值部分查询时,数据库字段名的数据类型要保证正确setInt
和setString
等被输入。
对于少于大约 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/