Java 如何设置已准备语句的参数列表?
我有一份名单,例如:Java 如何设置已准备语句的参数列表?,java,postgresql,jdbc,prepared-statement,Java,Postgresql,Jdbc,Prepared Statement,我有一份名单,例如: List<String> names = ... names.add('charles'); ... 如何执行以下操作: stmt.setParameterList(1,names); 有解决办法吗?有人能解释为什么缺少这种方法吗 使用:java、postgresql、jdbc3在我所知道的PreparedStatement上设置一个列表,是无法做到这一点的 编写代码,用适当数量的问号(与列表中的数字相同)构造SQL语句(或更好地替换单个?或类似标记)然后遍
List<String> names = ...
names.add('charles');
...
如何执行以下操作:
stmt.setParameterList(1,names);
有解决办法吗?有人能解释为什么缺少这种方法吗
使用:java、postgresql、jdbc3在我所知道的
PreparedStatement
上设置一个列表,是无法做到这一点的
编写代码,用适当数量的问号(与列表中的数字相同)构造SQL语句(或更好地替换单个?或类似标记)然后遍历列表,为每个设置参数。由于类型擦除,此方法丢失。列表的参数类型在运行时丢失。因此,需要添加几种方法:
setIntParameters
,setLongParameters
,setObjectParameters
,等等。对于postgres 9,我使用了这种方法:
jdbcTemplate.query(getEmployeeReport(), new PreparedStatementSetter() {
@Override
public void setValues(PreparedStatement ps) throws SQLException {
ps.setTimestamp(1, new java.sql.Timestamp(from.getTime()));
ps.setTimestamp(2, new java.sql.Timestamp(to.getTime()));
StringBuilder ids = new StringBuilder();
for (int i = 0; i < branchIds.length; i++) {
ids.append(branchIds[i]);
if (i < branchIds.length - 1) {
ids.append(",");
}
}
// third param is inside IN clause
// Use Types.OTHER avoid type check while executing query
ps.setObject(3, ids.toString(), **Types.OTHER**);
}
}, new PersonalReportMapper());
jdbcTemplate.query(getEmployeeReport(),new PreparedStatementSetter()){
@凌驾
public void setValues(PreparedStatement ps)引发SQLException{
ps.setTimestamp(1,新的java.sql.Timestamp(from.getTime());
ps.setTimestamp(2,新的java.sql.Timestamp(to.getTime());
StringBuilder ID=新的StringBuilder();
for(int i=0;i
今天早上我正在查看代码,我的一位同事有一种不同的方法,只需使用setString(“name1'、'name2'、'name3')传递参数即可。
注意:我跳过了开头和结尾的单引号,因为它们将由
设置字符串添加 这个问题很老了,但是没有人建议使用
这个答案可能有助于其他方法:
public void setValues(PreparedStatement ps) throws SQLException {
// first param inside IN clause with myList values
ps.setObject(1 , myList.toArray(), 2003); // 2003=array in java.sql.Types
}
在不同的论坛上检查了各种解决方案,但没有找到一个好的解决方案后,我觉得下面我提出的破解方法是最容易遵循和编写的。但是请注意,这并不使用准备好的查询,而是完成了工作:
示例:假设您有一个参数列表要在'in'子句中传递。只需在'IN'子句中放入一个伪字符串,例如,“PARAM”表示将取代该伪字符串的参数列表
select * from TABLE_A where ATTR IN (PARAM);
可以将所有参数收集到Java代码中的单个字符串变量中。这可以通过以下方式完成:
String param1 = "X";
String param2 = "Y";
String param1 = param1.append(",").append(param2);
在本例中,您可以将所有由逗号分隔的参数附加到单个字符串变量“param1”中
在将所有参数收集到一个字符串中之后,您只需将查询中的伪文本(在本例中为“PARAM”)替换为参数字符串(即param1)。以下是您需要做的:
String query = query.replaceFirst("PARAM",param1); where we have the value of query as
query = "select * from TABLE_A where ATTR IN (PARAM)";
现在可以使用executeQuery()方法执行查询。只要确保你的查询中没有“PARAM”这个词。您可以使用特殊字符和字母的组合,而不是单词“PARAM”,以确保查询中不可能出现此类单词。希望您能找到解决方案。如果问题的意思是在一次调用中设置多个参数
因为类型验证已经在更高的级别上定义了,所以我认为唯一需要的是
因此,可以使用实用方法:
public static void addParams(PreparedStatement preparedStatement, Object... params) throws SQLException {
for (int i = 0; i < params.length; i++) {
Object param = params[i];
preparedStatement.setObject(i+1, param);
}
}
请随意将其转换为Java 8 lambda:)如果每个数据类型都有一个add方法,为什么每个数据类型都没有一个“addList”方法呢?(例如addStringList(…))这就是问题所在,即使不计算列表变量,语句接口也已经膨胀。类型擦除不是一个好的原因,对于常量字符串可能有setArrayParameter(int-pos,Object[]params),这可能是可以接受的。对于用户输入,这是一个很好的例子,说明代码容易受到SQL注入的攻击。这绝对不应该起作用。如果是这样,您的JDBC驱动程序中就有一个bugsetString
处理撇号,这样您就可以实际获得传递的String
。你的同事测试过他们的代码吗?请对你的代码做一些解释这真的有效吗?你知道这可能会导致SQL注入吗?谢谢它有效…:)这真的适用于(?)
中的?一旦将实际语句发布到服务器,它会是什么样子?您希望避免在JDBC代码中串接字符串值,因为这很容易导致SQL注入错误-1setObject传递一个列表会引发Oracle driversetArray的异常。由于MySQL或JavaDB不支持SQL中的数组数据类型,因此它无法与MySQL或JavaDB一起使用。请参阅顶部的注释:@TigerC10好点。。。好奇激起了re:Java内存中数据库-Derby(JavaDB)不支持,但同时支持和。
public static void addParams(PreparedStatement preparedStatement, Object... params) throws SQLException {
for (int i = 0; i < params.length; i++) {
Object param = params[i];
preparedStatement.setObject(i+1, param);
}
}
SqlUtils.addParams(preparedStatement, 1, '2', 3d);