【发布时间】:2013-06-29 12:25:11
【问题描述】:
是否可以在不设置初始SQL查询的情况下在java中创建PreparedStatement?
示例代码:
@Override
public List<AccountBean> search(AccountConstraint... c) {
if (c.length == 0) {
throw new IllegalArgumentException("dao.AccountDAO.search: c.length == 0");
}
try {
List<AccountBean> beans = new ArrayList<>();
for (AccountConstraint ac : c) {
PreparedStatement ps = connection.prepareStatement(null);
QueryBuilder queryBuilder = new QueryBuilder(ps, "SELECT * FROM accounts");
queryBuilder.add(ac.getAccountIdConstraint());
queryBuilder.add(ac.getUsernameConstraint());
queryBuilder.add(ac.getPasswordConstraint());
queryBuilder.add(ac.getEmailConstraint());
//INSERT QUERY INTO PS
ResultSet rs = ps.executeQuery();
while (rs.next()) {
beans.add(new AccountBean(rs));
}
}
return beans;
} catch (SQLException ex) {
throw new RuntimeException(ex);
}
}
诀窍在于QueryBuilder,该类负责根据初始 SELECT 部分构建查询部分,然后添加相应的 WHERE 和 AND 子句。
然而,为了确保所有数据都是安全的,实际的参数也必须放在 PreparedStatement 中,这就是为什么要将它传递给 QueryBuilder。
每个QueryBuilder.add() 都会在 PreparedStatement 中添加一些参数,并在查询末尾附加一个特定的字符串。
我认为一些解决方法是可能的,例如,不要将PreparedStatement 提供给QueryBuilder,而是提供List<Object>,然后编写一个自定义函数,稍后将它们放入PreparedStatement。
但是您对此有何想法和建议?
问候。
已添加解决方案
首先进行一些关键更改:
-
QueryBuilder现在可以正确实现 Builder 模式。 -
QueryBuilder.add()一次接受多个Constraints。 -
AccountConstraint可以给出一个数组,现在给出所有Constraints。
@Override
public List<AccountBean> search(AccountConstraint... c) {
if (c.length == 0) {
throw new IllegalArgumentException("dao.AccountDAO.search: c.length == 0");
}
try {
List<AccountBean> beans = new ArrayList<>();
for (AccountConstraint ac : c) {
try (PreparedStatement ps = new QueryBuilder("SELECT * FROM accounts").add(ac.getConstraints()).build();ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
beans.add(new AccountBean(rs));
}
}
}
return beans;
} catch (SQLException ex) {
throw new RuntimeException(ex);
}
}
ps。由于 try-with-resources,我在一个 try{ } 中得到了两个语句。
【问题讨论】:
标签: java jdbc prepared-statement