在Java中使用JDBC时,通常接受的查询数据库的方法是获取连接,从该连接创建语句,然后从该语句执行查询。
// load driver
Connection con = DriverManager.getConnection(..);
Statement stmt = con.createStatement();
ResultSet result = stmt.executeQuery("SELECT..");
// ...
但是,我不确定如何处理对同一数据库的第二个查询。
可以在同一个Statement
对象上安全地执行另一个查询,还是必须从Connection
对象创建另一个语句才能执行另一个查询?
如果同一个Statement
对象可以用于多个查询,那么Statement
类的目的是什么(因为它对Connection.executeQuery()
方法更有意义存在)?
答案 0 :(得分:7)
是的,您可以重复使用Statement
对象,但ResultSet
返回的executeQuery
对象会关闭已打开的结果集。
有关说明,请参阅javadoc
默认情况下,每个Statement对象只能打开一个ResultSet对象 同时。因此,如果读取一个ResultSet对象是 与另一个的读取交错,每个必须已经生成 通过不同的Statement对象。 Statement中的所有执行方法 如果是,接口隐式关闭一个statment的当前ResultSet对象 打开一个。
所以发生以下情况:
// load driver
Connection con = DriverManager.getConnection(..);
Statement stmt = con.createStatement();
ResultSet result = stmt.executeQuery("select ..");
// do something with result ... or not
ResultSet result2 = stmt.executeQuery("select ...");
// result is now closed, you cannot read from it anymore
// do something with result2
stmt.close(); // will close the resultset bound to it
例如,您可以在jTDS项目中找到Statement的开源实现。
在Statement.executeQuery() method中,您可以看到已initialize()
已打开的closes all the resultsets来电
protected void initialize() throws SQLException {
updateCount = -1;
resultQueue.clear();
genKeyResultSet = null;
tds.clearResponseQueue();
// FIXME Should old exceptions found now be thrown instead of lost?
messages.exceptions = null;
messages.clearWarnings();
closeAllResultSets();
}
答案 1 :(得分:3)
以编程方式,您可以为多个查询重用相同的连接和相同的语句,并在最后关闭语句和连接。
然而,这不是一个好习惯。应用程序性能对数据库的访问方式非常敏感。理想情况下,每个连接应该在最短的时间内打开。然后,必须合并连接。通过这种方式,您可以将每个查询括在{open connection, create a prepared statement, run query, close statement, close connection}
的块中。这也是大多数SQL模板实现的方式。如果并发允许,您可以使用线程池同时触发多个此类查询。
答案 2 :(得分:2)
如果在线程环境中使用Connection和Statement,我有一件事要添加。 我的经验表明,stmt.executeQuery(..)被保存为在并行环境中使用,但结果是每个查询都被序列化并因此按顺序处理,而不是产生任何加速。 因此,最好为每个线程使用一个新的Connection(而不是Statement)。
对于标准顺序环境,我的经验表明,重用语句完全没有问题,并且不需要手动关闭ResultSet。
答案 3 :(得分:1)
这就是为什么我们在面向对象编程中有类的概念。类定义组成成员,使其实例具有状态和行为。这里语句处理与sql语句相关的所有内容。还有很多功能可以执行,如批处理查询等。
答案 4 :(得分:1)
通常,它是一个查询的一个语句。可能没有必要这样做,但在编写实际应用程序时,您不希望一次又一次地重复这些相同的步骤。这与DRY校长有关,而且随着应用程序的增长,它也将变得更加复杂。
编写处理这种低级(重复)内容的对象是很好的,并提供了通过提供查询来访问db的不同方法。
答案 5 :(得分:1)
我不担心创建新语句。但是,打开数据库连接可能会占用大量资源,而打开和关闭连接会影响性能。
以某种自我管理方式离开联系通常非常糟糕。
您应该考虑使用connection pooling。您通常会发出一个close命令,但是您只是将该连接返回到池中。当您请求新连接时,它将重用您之前提供的连接。
您可能希望为一个连接使用不同的语句。 Statement是一个实现和一个接口。根据您的需要,您有时需要使用CallableStatment。某些逻辑可能会在需要时重复使用。