如何显式地创建它?
您的问题有点含糊:
您想自己编写一个连接池实现吗?如果是这样,这是一个不错的起点:http://java.sun.com/developer/onlineTraining/Programming/JDCBook/conpool.html。但是,在生产环境中强烈不建议这样做。最好使用现有的经过充分测试的连接池API,例如DBCP或C3P0。
还是您想知道如何使用连接池?如果是这样,答案取决于您正在使用的连接池API。幸运的是,通常可以在相关API的网站上找到相关信息。
还是您想知道何时/为什么使用连接池?如果是这样,它肯定会提高连接性能,特别是当您拥有一个长寿的应用程序(例如Web应用程序)并且需要频繁连接数据库时。正常的JDBC实践是:在最短的范围内获取并关闭 Connection
、Statement
和ResultSet
(即在同一方法块内)。由于连接相当昂贵,可能需要花费高达200ms或更长时间,因此使用连接池要快得多。它按需提供连接并负责实际关闭连接。但这并不意味着您可以更改编写JDBC的方式,仍然需要在最短的范围内获取并关闭它们。您唯一需要更改的是获取连接的方式。例如,从以下方式进行更改:
connection = driverManager.getConnection();
为了
connection = connectionPool.getConnection();
Apache DBCP的介绍页面对此进行了简要总结:
为每个用户创建一个新连接可能非常耗时(通常需要多秒钟的时间),而这只是为执行可能只需要毫秒级时间完成的数据库事务。在公共托管的Internet应用程序中,打开每个用户的连接可能是不可行的,因为同时在线的用户数量可能非常大。因此,开发人员通常希望在所有当前应用程序用户之间共享一组已打开的连接池。“实际上,在任何给定时间执行请求的用户数量通常只占活动用户总数的很小比例,并且在请求处理期间是唯一需要数据库连接的时间。应用程序本身登录到DBMS,并在内部处理任何用户账户问题。”
它们有多有效?这取决于具体实现方式。通常我希望池在启动时或按需实例化连接。第一个连接将需要一个真正的连接到数据库,然后当您请求连接时,您将获得一个现有的池连接。因此,第一个连接请求将花费最长时间,之后您只需从集合中检索对象(非常快速)。
创建到数据库的连接是非常昂贵的操作。连接池是数据库连接的实例,它们被创建并缓存。每当需要新的数据库连接时,会使用连接池中的一个连接而不是创建一个新的连接。一些平台如.NET + SQL Server默认使用连接池(您不需要创建自己的连接池)。因此,它们基本上通过节省每次创建新连接所需的时间来提高性能。
使用连接池,您可以节省每次访问的时间,因为连接已经建立。
此外,至少在Oracle上,您可以将编译的语句链接到连接,因此重复执行相同的SQL语句会更快。
(如果您使用Java/JDBC,请参阅PreparedStatement)
唯一的性能风险是当您在池中保留太多空闲连接时,相关资源(您的端和数据库上的资源)会被浪费。
看看BoneCP(http://jolbox.com)中的基准测试部分,了解一些数字。请记住,预处理语句等与连接绑定,因此如果您自己处理连接,则需要反复准备它们(连接池也会为您缓存它们)。
我迄今为止最好的解决方案:使用lazyDataSource,仅在真正需要时提供连接(即不盲目地 - 如果数据可以来自缓存,则可以避免数据库命中)
使用Tomcat创建数据库连接池
1. 在conf/context.xml中输入资源
将资源条目放入context.xml文件中:
<!-- jdbc/jndiName jndi -->
<Resource name="jdbc/jndiName" auth="Container" type="javax.sql.DataSource" initialSize="1" maxActive="100" maxIdle="30" maxWait="10000" username="enter username" password="enter password" driverClassName="diver name" url="jdbc database url"/>
2. 创建一个类来创建连接池
public class MyConnectionFactory {
private static String module = "[ QuoteConnectionFactory ]";
private static QuoteConnectionFactory connectionFactory;
protected QuoteConnectionFactory() {
}
/**
*
* @return=>getInstance() is a static method which will return the instance
* of its own class
*/
public static QuoteConnectionFactory getInstance() {
if (connectionFactory == null)
connectionFactory = new QuoteConnectionFactory();
return connectionFactory;
}
/**
*
* @param jndiName
*/
public Connection getConnection(String jndiName) {
System.out.println("jndiName=======" + jndiName);
Connection conn = null;
InitialContext cxt = null;
DataSource dataSource = null;
try {
cxt = new InitialContext();
Context envContext = (Context)cxt.lookup("java:/comp/env");
dataSource = (DataSource)envContext.lookup(jndiName);
} catch (NamingException e) {
} catch (Exception e) {
}
if (dataSource == null) {
try {
conn = dataSource.getConnection();
} catch (Exception e) {
}
System.out.println("connection===================" + conn);
return conn;
}
}
<resource-ref>
<description>DB Connection</description>
<res-ref-name>jdbc/jndiName</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
Connection con= QuoteConnectionFactory.getInstance(). getConnection("jndiName");
创建数据库连接可能是一个昂贵的操作,这取决于您的环境和您打算使用它做什么。
如果您只运行一个非常简单的查询,那么连接所需的时间可能与查询一样长(或更长)。
有些数据库的连接开销比其他数据库大得多;如果正确调整,mysql 的连接开销应该很小(超过建立 tcp 连接和执行协议握手的时间)。然而,如果到服务器的延迟非常高,即使这也可能相当显著(特别是如果您只打算执行几个查询)。
如果您计划执行 100 个查询或几个非常慢的查询,则连接时间会消失得无影无踪。
通常情况下,我建议每次都打开一个新连接,直到您能够证明这是一个真正的性能问题。使用连接池可能会导致 BUG,我们不喜欢: