prepareStatement() 和 preparedStatement() 行为之间的区别

difference between prepareStatement() and preparedStatement() behaviour

我注意到有很多关于 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 - 定义为 table 列中的日期可以很好地处理手写日期)

我想要完成的是将最后一次更改行的时间存储为最后一个任务列,同时使用漂亮的 PreparedStatement 对象和数据库时间中的 set 方法作为无法真正调整的时间戳。如果有更好的方法,我愿意接受建议。

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

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

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 的原因。