我有一些JDBC代码如下:
String selectSQL = "SELECT * FROM DBUSER WHERE USER_ID = ? and PASSWORD = ?";
Integer userId = 1000;
char[] passwordString = new char[] { 't', 'e', 's', 't' };
PreparedStatement preparedStatement = dbConnection.prepareStatement(selectSQL);
preparedStatement.setInt(1, 1001);
preparedStatement.setArray(2,... ??? // how to do this part?
// execute select SQL statement
ResultSet rs = preparedStatement.executeQuery();
如何调用preparedStatement.setArray
在查询中设置第二个参数?我不想在这里使用字符串参数来保护密码。
注意我正在使用Hypersonic数据库,但如果有用,请计划移至MySql。
答案 0 :(得分:9)
PreparedStatement#setArray收到了java.sql.Array
首先,您应该使用JDBC Conncetion的createArrayOf方法创建数组,然后才能将其传递给setArray
。
由于该方法只接受Object[]
,您应该创建一个Character
而不是char的数组。
例如:
Character[] passwordString = new Character[] { 't', 'e', 's', 't' };
Array sqlArray = con.createArrayOf("CHAR", passwordString);
preparedStatement.setArray(2, sqlArray);
答案 1 :(得分:2)
如果要在预准备语句中传递数组,请调用
preparedStatemtn.setArray(index,array);
但首先要确保的是,在您的数据库中,该列也是ARRAY。有关详细信息,请参阅Aviram Sagal的答案。
但你的基础是保护密码。
此解决方案仅保护不从Java字符串池中读取passoword。无论如何,这是非常类型的接触。 Ans passoword作为纯文本传播。
我的理解是,您应该使用加密技术的一些好处,而不是使数据库模式复杂化。如果传递密码值,则应传递password digest。
一个简化的摘要功能示例。
public static String getDigest(byte[] password) {
return new String(Hex.encodeHex(new MessageDigest.getInstance("SHA").digest(password)));
}
然后你在db中存储了一个安全的摘要,你在查询中使用简单的字符串。
答案 2 :(得分:1)
看一下这段代码
final PreparedStatement statement = connection.prepareStatement(
"SELECT my_column FROM my_table " +
"where search_column IN (SELECT * FROM unnest(?))"
);
final String[] values = getValues();
statement.setArray(1, connection.createArrayOf("text", values));
final ResultSet rs = statement.executeQuery();
try {
while(rs.next()) {
// do some...
}
} finally {
rs.close();
}
另请参阅此文章以获取参考http://people.apache.org/~djd/derby/publishedapi/java/sql/PreparedStatement.html
答案 3 :(得分:0)
另一种方法是使用CharArrayReader
并调用statement.setCharacterStream
。
char[] passwordString = new char[] { 't', 'e', 's', 't' };
statement.setCharacterStream(1, new CharArrayReader(passwordString));