【问题标题】:difference between prepareStatement() and preparedStatement() behaviourprepareStatement() 和preparedStatement() 行为之间的区别
【发布时间】:2015-02-16 23:11:23
【问题描述】:

我注意到有很多关于 CreateStatement 与 PreparedStatement 的帖子,但是我的问题不同(只是为了通知这不是这些搜索结果之一的重复)

当我从 java 代码中查询数据库时,我可以通过(至少)两种方式进行:

PreparedStatement对象:

String quer =  "insert into table1 (name, phone, bday, lastasked);
PreparedStatenent pst = con.prepareStatement(quer);
pst.setString(1, "Stacy");
pst.setString(2, "555-0123456");
pst.setString(3, bdayFromInput);
pst.setString(4, "now()"); //should invoke sql now() function
pst.execute()

构建整个查询:

String query = "insert into table1 (name, phone, bday, lastasked) VALUES ('Stacy', '555-123456', '" + bdayFromInput + "',  now());";
try{
    con.prepareStatement(query).execute();
}catch (SQLException e){
    System.err.println("sql exception occured");
}

问题与 sql 中的“now()”函数有关 - 我猜是有某种包装器将 setString 转换为实际字符串(根据 'now()') - 使指令无效(尤其是字符串 bday - 被定义为表格列中的日期可以很好地与手写日期一起使用)

我想要完成的是将上次更改行的时间存储为 lastasked 列,同时使用漂亮的 PreparedStatement 对象并将数据库时间中的方法设置为无法真正调整的时间戳。如果有更好的方法,我愿意接受建议。

我想使用 PreparedStatement 对象的原因是易于处理 blob - 我想稍后插入带有照片和个人日记/笔记的 blob,这将构成两个单独的 blob,而 VARCHAR 或 LONG VARCHAR 可能很好简短的笔记足够了,我认为对于较长的文本来说就不够了,而且肯定对图片没有用处

【问题讨论】:

  • “我的猜测是有某种包装器可以将 setString 转换为实际的字符串(根据 'now()')” - 是的,这实际上是准备好的查询的一半。它可以防止某些类型的攻击。

标签: java sql hsqldb


【解决方案1】:

您可以混合使用这两种方法:

String sql= "insert into table1 (name, phone, bday, lastasked) values (?,?,?,now())";
PreparedStatenent pst = con.prepareStatement(sql);
pst.setString(1, "Stacy");
pst.setString(2, "555-0123456");
pst.setString(3, bdayFromInput);
pst.execute();

注意,您的第二种方法容易受到 SQL 注入的影响,这就是为什么在向 JDBC 驱动程序传递值时建议使用 PreparedStatement。

【讨论】:

  • 感谢您指出 SQL 注入风险 - 虽然代码是包装类的一部分,但我什至不认为有人会尝试将 SQL 函数作为名称或其他参数插入 - 我会按照您的建议混合方法,再次感谢您指出注入风险
猜你喜欢
  • 2015-05-13
  • 2014-08-31
  • 1970-01-01
  • 2011-03-17
  • 2015-11-18
  • 2018-06-02
  • 2015-09-10
  • 2012-04-21
相关资源
最近更新 更多