Java中准备好的语句对象放在哪里?
我想使用事先准备好的语句。我已经读到,预先准备好的语句的优点是它们不必每次都被解析/编译,这样可以减少负载。现在我的问题是,在Java中还是在我的DB系统中,“识别”已经准备好的语句发生在哪里?我这样问是因为我想知道在代码中把PreparedStatement对象存储在哪里:作为class属性,并为每个请求设置参数,或者在有请求时创建一个新的PreparedStatement对象Java中准备好的语句对象放在哪里?,java,jdbc,prepared-statement,Java,Jdbc,Prepared Statement,我想使用事先准备好的语句。我已经读到,预先准备好的语句的优点是它们不必每次都被解析/编译,这样可以减少负载。现在我的问题是,在Java中还是在我的DB系统中,“识别”已经准备好的语句发生在哪里?我这样问是因为我想知道在代码中把PreparedStatement对象存储在哪里:作为class属性,并为每个请求设置参数,或者在有请求时创建一个新的PreparedStatement对象 public class Option1 { private PreparedStatemen
public class Option1 {
private PreparedStatement myStatement;
public Option1() {
// create the myStatement object
myStatement = conn.prepareStatement("");
}
public List<Items> query() {
// just use the myStatement object
myStatement.setString(1, "foo");
}
}
public class Option2 {
public List<Items> query() {
PreparedStatement myLocalStatement = conn.prepareStatement("");;
// create and use the statement
myLocalStatement.setString(1, "foo");
}
}
公共类选项1{
私人编制的声明或声明;
公共选择1(){
//创建myStatement对象
myStatement=conn.preparest陈述(“”);
}
公共列表查询(){
//只需使用myStatement对象
myStatement.setString(1,“foo”);
}
}
公共类选项2{
公共列表查询(){
PreparedStatement myLocalStatement=conn.prepareStatement(“”);;
//创建并使用语句
myLocalStatement.setString(1,“foo”);
}
}
现在我的问题是,更好的方法是什么,选项1还是选项2?但是,我必须在每次执行后通过执行myStatement.close()
来进行“清理”,对吗
也许我应该用另一种方式问它:如何以最有效的方式重用它
更新:如果有两个答案,一个选择1,一个选择2,我会恳请社区投票支持他们的选择^^我会选择选项1:ie
public class Option1 {
private PreparedStatement myStatement;
public Option1() {
// create the myStatement object
myStatement.setString(1, "foo");
}
public List<Items> query() {
// just use the myStatement object
}
}
公共类选项1{
私人编制的声明或声明;
公共选择1(){
//创建myStatement对象
myStatement.setString(1,“foo”);
}
公共列表查询(){
//只需使用myStatement对象
}
}
原因:
我可以在需要时为其指定新对象。通过做这样的事情
pst=con.preparest陈述(myQuery)代码>在函数中,在您的情况下,函数将是Option1()
我建议使用选项2
public class Option2 {
public List<Items> query() {
PreparedStatement myLocalStatement = conn.prepareStatement("");;
// create and use the statement
myLocalStatement.setString(1, "foo");
}
}
SQL数据库正在以完整查询(包括where
子句)为键缓存语句的执行计划。通过使用准备好的语句,无论使用什么值,查询都是相同的(它们始终是“?”)
因此,从数据库缓存的角度来看,这两个选项之间没有区别。请参阅,这还描述了一些特定于JavaEE的问题
但是当然,从代码的角度来看还有一些其他因素,正如其他人提到的,尤其是当您经常重用它时(如中)。重要的是,一些JDBC驱动程序正在支持它。
请记住,事先准备好的语句在开始时会变得过于繁杂,而随后的每一次使用都会使语句变得繁杂——这里有一个。就我个人而言,我喜欢第二个选项,这就是我的想象
public void addAccount(String username, String password, String name) {
String query="INSERT INTO Accounts (username, password, name) VALUES (?,?,?)";
try(Connection connection = dataSource.getConnection()) {
try(PreparedStatement statement = connection.preparedStatement(query)){
statement.setString(1, username);
statement.setString(2, password);
statement.setString(3, name);
statement.executeUpdate();
}
} catch(SQLException e) {
e.printStacktrace();
}
之所以应该使用try with resource,是因为它处理常见的编码错误,例如发生错误时关闭。这也保证了在执行之后,您的语句/连接/结果集将被关闭(或任何其他问题)如果您不重用一个准备好的语句,它有什么用?@Tichodroma避免SQL注入(当然,有其他方法可以获得相同的结果)问题是如何以最有效的方式重用它。@Tichodroma这是我的观点;-)因此,我问DB系统是否识别已经准备好的语句(字符串比较或其他),或者我是否必须使用相同的对象来处理这个问题。。。当查询被发送到DB系统时,“preparedStatement()”的使用可能会给查询添加一个标志?!首先,不要盲目相信你读到的建议。量!一些数据库驱动程序在准备时做了大量的工作,以至于需要数百次调用已准备好的语句,才能在总时间内完成工作。
Option2 myQuery = new Option2();
myQyery.query("SELECT * FROM PERSON WHERE NAME = :?","ANY_NAME");
public void addAccount(String username, String password, String name) {
String query="INSERT INTO Accounts (username, password, name) VALUES (?,?,?)";
try(Connection connection = dataSource.getConnection()) {
try(PreparedStatement statement = connection.preparedStatement(query)){
statement.setString(1, username);
statement.setString(2, password);
statement.setString(3, name);
statement.executeUpdate();
}
} catch(SQLException e) {
e.printStacktrace();
}