我正在用 JSP 开发一个小 Web 应用程序,这个应用程序需要一个数据库连接,我提供了一个 servlet。
问题是,我希望服务器上的所有文件都可以使用这个类来访问数据库,而无需每次都创建新连接,实际上在每个文件中我都会创建一个新Database
对象并且每次都会建立一个新连接.
有没有办法避免这种情况,也许声明一个全局对象,例如session
and request
,这样它只会被初始化一次,然后被我的所有 JSP 文件使用?
谢谢
我正在用 JSP 开发一个小 Web 应用程序,这个应用程序需要一个数据库连接,我提供了一个 servlet。
问题是,我希望服务器上的所有文件都可以使用这个类来访问数据库,而无需每次都创建新连接,实际上在每个文件中我都会创建一个新Database
对象并且每次都会建立一个新连接.
有没有办法避免这种情况,也许声明一个全局对象,例如session
and request
,这样它只会被初始化一次,然后被我的所有 JSP 文件使用?
谢谢
你为什么想做这个?这两种解决方案都是错误的方法。
这是一个坏主意,因为数据库连接不是线程安全的。创建全局对象会降低应用程序的吞吐量,因为每个用户都必须共享连接。
更好的解决方案是拥有一个由应用服务器维护的连接池。执行 JNDI 查找以检查池外的连接,在尽可能窄的范围内使用它,并在该方法范围内关闭连接。
您的应用程序将更好地扩展,并且不会冒线程安全的风险。
您不需要全局变量,您需要为您的上下文提供一个功能,该功能将由您的应用程序使用。所以你需要使用 JNDI,在 Tomcat 网页中你有一个怎么做的,它解释得很好,也很容易实现。此致。
http://tomcat.apache.org/tomcat-7.0-doc/jndi-datasource-examples-howto.html
您似乎在谈论直接使用 JSP 文件中的数据库连接,不是吗?好吧,这不是一个理论上正确的解决方案,因为遵循关注点分离原则,您的视图(您的 JSP 文件)不应该对数据库或数据访问一无所知。检查 MVC 模式的任何描述,例如这很明显;-):
但是,如果您想采取捷径并让您的视图了解您的数据库,那么在我看来,您有两个选项,它们都涉及对先前在您的应用程序中定义的数据源的 JNDI 查找,正如Marcelo Tataje已经说过的那样。
关于如何在 Tomcat 上定义基于连接池的 JNDI 数据源:
http://tomcat.apache.org/tomcat-6.0-doc/jndi-datasource-examples-howto.html
在同一页面中,您可以看到如何使用此连接池直接从您的 JSP 发出查询(在我看来,这也是非常不可取的)
<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<sql:query var="rs" dataSource="jdbc/TestDB">
select id, foo, bar from testdata
</sql:query>
<html>
<head>
<title>DB Test</title>
</head>
<body>
<h2>Results</h2>
<c:forEach var="row" items="${rs.rows}">
Foo ${row.foo}<br/>
Bar ${row.bar}<br/>
</c:forEach>
</body>
</html>
另一个稍微好一点的解决方案是,在您的 java 代码中,JNDI 从您的上下文侦听器中像这样查找数据源:
public void contextInitialized(ServletContextEvent contextEvent) {
// JNDI Datasource lookup
InitialContext context = new InitialContext();
DataSource dataSource = (DataSource) context
.lookup("jdbc/DataSource");
// Storing datasource in application context
contextEvent.getServletContext().setAttribute("datasource",dataSource);
}
然后从任何 servlet 使用该存储的数据源来获取您需要的数据库连接,如下所示
((DataSource)contextEvent.getServletContext().getAttribute("datasource")).getConnection()
请不要直接使用 Connection 类。它非常原始和过时。如今,没有人在严肃的工作环境中处理这样的连接。如果你按照AmitG 的建议去做,你最终会得到一个由所有并发访问共享的唯一连接。看看这个为什么这不是要走的路