使用 PreparedStatement 附加到查询
Appending to a query using PreparedStatement
我有以下查询 PostgreSQL 数据库的函数片段:
private void setQuery(String col1, String col2, String col3) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(
" SELECT t1.id,t1.uuid, t2.client_id,t1.start_time, t1.end_time, t1.state FROM t1, t2 WHERE t1.id=t2.id"
);
if (col1 != null && !col1.isEmpty()) {
stringBuilder.append(" AND t1.col1 = ?");
}
if (col2 != null && !col2.isEmpty()) {
stringBuilder.append(" AND t1.col2 = ?");
}
if (col3 != null && !col3.isEmpty()) {
stringBuilder.append(" AND t1.col3 = ?");
}
PreparedStatement pstmt = null;
try (Connection connection = connectionProvider.getConnection()) {
pstmt = connection.prepareStatement(stringBuilder.toString());
// how can I set the ? values in the stringBuilder, since they can be empty?
// pstmt.setString(1, col1);
// pstmt.setString(2, col2);
// pstmt.setString(3, col3);
} finally {
if (pstmt != null) pstmt.close();
}
}
注意 col1
、col2
、col3
可以为空或 null,我需要 add/remove 来自 SQL 查询的那些变量,以防它们empty/null 与否。理想情况下,我希望被允许附加到 PreparedStatement,但我不知道这怎么可能。
实现这一目标的最佳方法是什么?如何将值正确设置到准备好的语句中?
你可以试试这个方法:
private void setQuery(String col1, String col2, String col3) throws SQLException {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(
" SELECT t1.id, t1.uuid, t2.client_id, t1.start_time, t1.end_time, t1.state FROM t1, t2 WHERE t1.id = t2.id "
);
List<String> optionalParams = new ArrayList<>();
if (col1 != null && !col1.isEmpty()) {
stringBuilder.append(" AND t1.col1 = ?");
optionalParams.add(col1);
}
if (col2 != null && !col2.isEmpty()) {
stringBuilder.append(" AND t1.col2 = ?");
optionalParams.add(col2);
}
if (col3 != null && !col3.isEmpty()) {
stringBuilder.append(" AND t1.col3 = ?");
optionalParams.add(col3);
}
try (Connection connection = connectionProvider.getConnection();
PreparedStatement pstmt = connection.prepareStatement(stringBuilder.toString()) {
for(int i = 1; i < optionalParams.size(); i++) {
pstmt.setString(i, optionalParams.get(i));
}
}
}
一些提示:
- 你也可以把
PreparedStatement
放在try-with-resource
语句中,然后去掉finally
块。
- 如果您的
setQuery
不在循环中,您可以简单地使用 +
运算符而不是 StringBuilder
来缩短代码。
我有以下查询 PostgreSQL 数据库的函数片段:
private void setQuery(String col1, String col2, String col3) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(
" SELECT t1.id,t1.uuid, t2.client_id,t1.start_time, t1.end_time, t1.state FROM t1, t2 WHERE t1.id=t2.id"
);
if (col1 != null && !col1.isEmpty()) {
stringBuilder.append(" AND t1.col1 = ?");
}
if (col2 != null && !col2.isEmpty()) {
stringBuilder.append(" AND t1.col2 = ?");
}
if (col3 != null && !col3.isEmpty()) {
stringBuilder.append(" AND t1.col3 = ?");
}
PreparedStatement pstmt = null;
try (Connection connection = connectionProvider.getConnection()) {
pstmt = connection.prepareStatement(stringBuilder.toString());
// how can I set the ? values in the stringBuilder, since they can be empty?
// pstmt.setString(1, col1);
// pstmt.setString(2, col2);
// pstmt.setString(3, col3);
} finally {
if (pstmt != null) pstmt.close();
}
}
注意 col1
、col2
、col3
可以为空或 null,我需要 add/remove 来自 SQL 查询的那些变量,以防它们empty/null 与否。理想情况下,我希望被允许附加到 PreparedStatement,但我不知道这怎么可能。
实现这一目标的最佳方法是什么?如何将值正确设置到准备好的语句中?
你可以试试这个方法:
private void setQuery(String col1, String col2, String col3) throws SQLException {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(
" SELECT t1.id, t1.uuid, t2.client_id, t1.start_time, t1.end_time, t1.state FROM t1, t2 WHERE t1.id = t2.id "
);
List<String> optionalParams = new ArrayList<>();
if (col1 != null && !col1.isEmpty()) {
stringBuilder.append(" AND t1.col1 = ?");
optionalParams.add(col1);
}
if (col2 != null && !col2.isEmpty()) {
stringBuilder.append(" AND t1.col2 = ?");
optionalParams.add(col2);
}
if (col3 != null && !col3.isEmpty()) {
stringBuilder.append(" AND t1.col3 = ?");
optionalParams.add(col3);
}
try (Connection connection = connectionProvider.getConnection();
PreparedStatement pstmt = connection.prepareStatement(stringBuilder.toString()) {
for(int i = 1; i < optionalParams.size(); i++) {
pstmt.setString(i, optionalParams.get(i));
}
}
}
一些提示:
- 你也可以把
PreparedStatement
放在try-with-resource
语句中,然后去掉finally
块。 - 如果您的
setQuery
不在循环中,您可以简单地使用+
运算符而不是StringBuilder
来缩短代码。