我正在开发一个简单的CRUD应用程序,使用JDBC建立连接并执行基本的CRUD操作。在该过程中,创建了一个DatabaseListener,用于在启动时创建连接对象,并将其存储在上下文属性中以供重用。
以下是代码。
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.apache.log4j.Logger;
public class DatabaseInitListner implements ServletContextListener {
private static final Logger LOG = Logger.getLogger(DatabaseInitListner.class);
private DBUtil databaseUtil = null;
@Override
public void contextDestroyed(ServletContextEvent event) {
databaseUtil.closeConnection();
}
@Override
public void contextInitialized(ServletContextEvent contextinitEvent) {
ServletContext servletContext = contextinitEvent.getServletContext();
String database = servletContext.getInitParameter("db_name");
String url = servletContext.getInitParameter("db_url")
+ database;
String username = servletContext.getInitParameter("db_user");
String password = servletContext.getInitParameter("db_password");
String driverName = servletContext.getInitParameter("db_driver");
databaseUtil = new DBUtil(url, username, password,
driverName);
servletContext.setAttribute("databaseSingleConnectionObject",
databaseUtil.getConnection());
}
}
public class DBUtil {
private Connection connection = null;
private static final Logger LOG = Logger.getLogger(DatabaseUtil.class);
public DatabaseUtil(String url, String username, String password,
String driver) {
try {
Class.forName(driver);
this.connection = DriverManager.getConnection(url, username,
password);
LOG.debug("Connection Established... ");
} catch (ClassNotFoundException | SQLException e) {
LOG.error("Could not create connection... ", e);
}
}
public Connection getConnection() {
return connection;
}
public void closeConnection() {
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
LOG.error("Unable to close connection... ", e);
}
}
}
}
我在这样的servlet中访问连接
Connection jdbcConnection = (Connection) getServletContext().getAttribute("databaseSingleConnectionObject");
我不确定这是否正确。单个数据库连接有什么影响?
答案 0 :(得分:3)
当您使用这样的单个数据库连接时,您的应用程序会变得缓慢而脆弱。
慢:因为连接实现是同步的,所以每个用户都必须等到连接空闲。如果一个用户的查询需要一段时间才能返回,这会直接增加任何其他并发用户等待的时间。如果池中有多个连接可用,那么一个用户花费的时间几乎不会对其他用户造成太大影响(除非查询的结果占用了所有JVM的内存或大型查询使数据库服务器陷入困境)。
脆弱:连接是网络连接,它们往往会关闭。如果没有创建新连接的规定,任何类型的超时,网络打嗝或数据库不可用的时间段(例如使数据库脱机以进行维护)将需要重新启动应用程序。使用连接池意味着您的应用程序将能够在这些剧集中存活并在没有外部干预的情况下恢复。
答案 1 :(得分:2)
这不是线程安全的,如果是,那么性能将非常差。 考虑使用连接池,如DBCP或C3PO
答案 2 :(得分:1)
您应该让您的应用程序服务器管理数据库连接。在其配置文件中添加JNDI数据源,并从应用程序中进行查找以在需要时获取连接(例如,当您实例化必须访问数据库的类时)。 您可以配置数据源以管理连接池,以便每个用户会话都可以获得自己的连接池。 根据您使用的AS,使用关键字' JNDI'进行搜索。和'数据源'您将获得有关AS配置以及如何在您的应用程序中实现它的更多详细信息。