Java Servlet 中的数据库连接池
Database Connection Pooling in Java Servlets
我正在为员工管理系统创建一个 Web 应用程序,使用:Apache Tomcat 作为 HTTP 服务器,Oracle 作为数据库,Applet 用于客户端编程,Servlet 用于服务器端编程。我还想使用 DBCP 来管理与数据库的连接。
我希望执行查询的 servlet 使用客户端输入的用户名和密码进行连接。但是到目前为止我看到在context.xml
.
中配置资源时必须设置连接池的用户名和密码
有什么方法可以做到这一点并且仍然使用 DBCP?或者我是否必须为每个请求打开 doGet()
和 doPost()
中的连接?
如评论中所述,通常情况下,限制逻辑是在应用程序端而不是数据库端完成的。
但是如果您真的想使用数据库安全模型,那么您需要为每个登录用户创建单独的数据源 (ConnectionPool) 并将其存储在其会话中。如果您有很多并发访问,您很快就会发现您 运行 资源不足。
例如,我使用的是 DataSource,因为它更容易配置,但您可以使用任何连接池实现。
在登录操作中创建新的数据源(例如使用 apache common:http://commons.apache.org/proper/commons-dbcp/)并插入到会话中
BasicDataSource ds = new BasicDataSource();
...
ds.setPassword(userPassword);
ds.setUserName(login);
...
HttpSession session = request.getSession();
session.setAttribute("DBcon",ds);
在你的另一个 gets/posts:
HttpSession session = request.getSession();
DataSource ds = (DataSource)session.getAttribute("DBcon");
由于每个用户一个数据源,请确保使用池的一些低参数,例如 size=3,因为它对一个用户来说应该足够了。
DataSource::getConnection(String username, String password)
DataSource
界面有一个方法专门用于您的目的:改变每个连接的名称和密码,同时使用所有其他先前设置的连接选项:DataSource::getConnection(String username, String password)
java.sql.ConnectionPoolDataSource
接口带有相同类型的方法,getPooledConnection(String user, String password)
。因此,您的特定连接池实现可能支持这一点。
public javax.sql.DataSource obtainDataSource() {
org.postgresql.ds.PGSimpleDataSource dataSource = new PGSimpleDataSource() ;
dataSource("AcmeInvoices database data source") ;
source.setServerName( "localhost" ) ;
source.setDatabaseName( "invoicing" ) ;
// source.setUser( "Scott" ) ;
// source.setPassword( "tiger" ) ;
return dataSource ; // Returning a reference to the object of this concrete class `PGSimpleDataSource` as an object of the interface `DataSource`.
}
在做一些数据库工作时:
Connection conn = myDataSource.getConnection( "Scott" , "tiger" ) ;
… run SQL
conn.close() ; // Or better yet: Use try-with-resources syntax to automatically close the connection.
有关更多讨论,请参阅 an Answer of mine 相关问题。
参见 Oracle Tutorial on DataSource
。
我正在为员工管理系统创建一个 Web 应用程序,使用:Apache Tomcat 作为 HTTP 服务器,Oracle 作为数据库,Applet 用于客户端编程,Servlet 用于服务器端编程。我还想使用 DBCP 来管理与数据库的连接。
我希望执行查询的 servlet 使用客户端输入的用户名和密码进行连接。但是到目前为止我看到在context.xml
.
有什么方法可以做到这一点并且仍然使用 DBCP?或者我是否必须为每个请求打开 doGet()
和 doPost()
中的连接?
如评论中所述,通常情况下,限制逻辑是在应用程序端而不是数据库端完成的。
但是如果您真的想使用数据库安全模型,那么您需要为每个登录用户创建单独的数据源 (ConnectionPool) 并将其存储在其会话中。如果您有很多并发访问,您很快就会发现您 运行 资源不足。
例如,我使用的是 DataSource,因为它更容易配置,但您可以使用任何连接池实现。
在登录操作中创建新的数据源(例如使用 apache common:http://commons.apache.org/proper/commons-dbcp/)并插入到会话中
BasicDataSource ds = new BasicDataSource();
...
ds.setPassword(userPassword);
ds.setUserName(login);
...
HttpSession session = request.getSession();
session.setAttribute("DBcon",ds);
在你的另一个 gets/posts:
HttpSession session = request.getSession();
DataSource ds = (DataSource)session.getAttribute("DBcon");
由于每个用户一个数据源,请确保使用池的一些低参数,例如 size=3,因为它对一个用户来说应该足够了。
DataSource::getConnection(String username, String password)
DataSource
界面有一个方法专门用于您的目的:改变每个连接的名称和密码,同时使用所有其他先前设置的连接选项:DataSource::getConnection(String username, String password)
java.sql.ConnectionPoolDataSource
接口带有相同类型的方法,getPooledConnection(String user, String password)
。因此,您的特定连接池实现可能支持这一点。
public javax.sql.DataSource obtainDataSource() {
org.postgresql.ds.PGSimpleDataSource dataSource = new PGSimpleDataSource() ;
dataSource("AcmeInvoices database data source") ;
source.setServerName( "localhost" ) ;
source.setDatabaseName( "invoicing" ) ;
// source.setUser( "Scott" ) ;
// source.setPassword( "tiger" ) ;
return dataSource ; // Returning a reference to the object of this concrete class `PGSimpleDataSource` as an object of the interface `DataSource`.
}
在做一些数据库工作时:
Connection conn = myDataSource.getConnection( "Scott" , "tiger" ) ;
… run SQL
conn.close() ; // Or better yet: Use try-with-resources syntax to automatically close the connection.
有关更多讨论,请参阅 an Answer of mine 相关问题。
参见 Oracle Tutorial on DataSource
。