gpt4 book ai didi

java - 在JSP中,Singleton如何正确收场?

转载 作者:行者123 更新时间:2023-11-30 04:11:52 24 4
gpt4 key购买 nike

我刚开始使用jsp,我的问题是-当我有单例课程时,如何整理它?

尤其是:

public class DBConnection {
private static Connection connection = null;
private static Statement statement = null;

public static ResultSet executeQuery(String query){
if (connection == null) { /*initConnection*/ }
if (statement == null) { /*initStatement*/ }

// do some stuff
}
}


现在,我在几页中使用该类从jdbc获取结果。但是,我最终需要调用 statement.close();connection.close();-什么时候应调用它们?

我使用的是singleton,因为每次需要进行查询时,一次又一次地要求连接到数据库感觉不对。

最佳答案

Connection必须始终关闭,并且在执行了所需操作的所有数据库语句之后。两个例子:

情况1:您必须显示按数据库中条件过滤的供用户使用的产品列表。解决方案:建立连接,使用过滤条件检索产品列表,关闭连接。

情况2:客户选择其中一些产品,并更新最低库存以获得警报并重新库存。解决方案:建立连接,更新所有产品,然后关闭连接。

基于这些情况,我们可以学到很多东西:


在打开/保持单个连接的同时,您可以执行多个语句。
该连接应仅存在于使用它的块中。它不应在此之前或之后存在。
由于这两种情况都在多线程环境中,因此可以同时发生。因此,为了避免结果问题,两个线程不能同时使用单个数据库连接。例如,用户A搜索Foo类别中的产品,用户B搜索Bar类别中的产品,您不想向用户A显示Bar类别中的产品。
从最后一句话开始,每个数据库操作((或类似情况2的一组类似操作)都应在原子操作中进行处理。为确保这一点,连接一定不能存储在单例对象中,而只能存在于方法中正在使用。


结果:


不要将ConnectionStatementResultSet或其他JDBC资源声明为static。它只会失败。而是只将Connection声明为DBConnection类的字段。让每个方法决定处理每个Statement(或PreparedStatement)和ResultSet以及特定的JDBC资源。
由于必须在使用后关闭连接,因此请添加另外两个方法:void open()void close()。这些方法将处理数据库连接的检索并关闭该连接。
另外,由于DBConnection看起来像是Connection类和数据库连接操作的包装器类,我建议至少再使用三个方法:void setAutoCommit(boolean autoCommit)void commit()void rollback()。这些方法分别是Connection#setAutoCommit Connection#closeConnection#rollback的普通包装。


然后,您可以通过以下方式使用该类:

public List<Product> getProducts(String categoryName) {
String sql = "SELECT id, name FROM Product WHERE categoryName = ?";
List<Product> productList = new ArrayList<Product>();
DBConnection dbConnection = new DBConnection();
try {
dbConnection.open();
ResultSet resultSet = dbConnection.executeSelect(sql, categoryName); //execute select and apply parameters
//fill productList...
} catch (Exception e) {
//always handle your exceptions
...
} finally {
//don't forget to also close other resources here like ResultSet...
//always close the connection
dbConnection.close();
}
}


请注意,在此示例中, PreparedStatement不在 getProducts方法中,它将是 executeSelect方法的局部变量。

补充说明:


在应用程序服务器中工作时,您不应天真地打开连接,例如使用 Class.forName("..."),而不是使用数据库连接池。您可以像下面的说明一样使用某些数据库连接池库,例如C3P0: How to establish a connection pool in JDBC?。或在您的应用程序服务器中配置一个,如我在此处所述: Is it a good idea to put jdbc connection code in servlet class?
如果这是出于学习目的,请滚动自己的类来处理与数据库的通信。在实际应用中,不建议这样做(并不意味着您不应该这样做)。相反,请使用数据库连接框架,例如ORM,例如 JPA(Java官方ORM框架)或 Hibernate;没有像 Spring JDBCMyBatis这样的用于处理数据库通信的ORM框架。这是你的选择。


更多信息:


Should a database connection stay open all the time or only be opened when needed?
How do servlets work? Instantiation, sessions, shared variables and multithreading。与您的问题没有直接关系,但是它将帮助您理解为什么不维护多线程环境中使用的资源中的状态。

关于java - 在JSP中,Singleton如何正确收场?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19411468/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com