1.数据库连接池概述
数据库连接的建立是一种耗时、性能低、代价高的操作,频繁的数据库连接的建立和关闭极大的影响了系统的性能。数据库连接池是系统初始化过程中创建一定数量的数据库连接放于连接池中,当程序需要访问数据库时,不再建立一个新的连接,而是从连接池中取出一个已建立的空闲连接,使用完毕后,程序将连接归还到连接池中,供其他请求使用,从而实现的资源的共享,连接的建立、断开都由连接池自身来管理。
数据库连接池为系统的运行带来了以下优势:昂贵的数据库连接资源得到重用;减少了数据库连接建立和释放的时间开销,提高了系统响应速度;统一的数据库连接管理,避免了连接资源的泄露。
数据库连接池运行机制:
系统初始化时创建连接池,程序操作数据库时从连接池中获取空闲连接,程序使用完毕将连接归还到连接池中,系统退出时,断开所有数据库连接并释放内存资源。
2.主流数据库连接池比较
常用的主流开源数据库连接池有C3P0、DBCP、Tomcat Jdbc Pool、BoneCP、Druid等
C3p0: 开源的JDBC连接池,实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。目前使用它的开源项目有hibernate、spring等。单线程,性能较差,适用于小型系统,代码600KB左右。
DBCP (Database Connection Pool):由Apache开发的一个Java数据库连接池项目, Jakarta commons-pool对象池机制,Tomcat使用的连接池组件就是DBCP。单独使用dbcp需要3个包:common-dbcp.jar,common-pool.jar,common-collections.jar,预先将数据库连接放在内存中,应用程序需要建立数据库连接时直接到连接池中申请一个就行,用完再放回。单线程,并发量低,性能不好,适用于小型系统。
Tomcat Jdbc Pool:Tomcat在7.0以前都是使用common-dbcp做为连接池组件,但是dbcp是单线程,为保证线程安全会锁整个连接池,性能较差,dbcp有超过60个类,也相对复杂。Tomcat从7.0开始引入了新增连接池模块叫做Tomcat jdbc pool,基于Tomcat JULI,使用Tomcat日志框架,完全兼容dbcp,通过异步方式获取连接,支持高并发应用环境,超级简单核心文件只有8个,支持JMX,支持XA Connection。
BoneCP:官方说法BoneCP是一个高效、免费、开源的Java数据库连接池实现库。设计初衷就是为了提高数据库连接池性能,根据某些测试数据显示,BoneCP的速度是最快的,要比当时第二快速的连接池快25倍左右,完美集成到一些持久化产品如Hibernate和DataNucleus中。BoneCP特色:高度可扩展,快速;连接状态切换的回调机制;允许直接访问连接;自动化重置能力;JMX支持;懒加载能力;支持XML和属性文件配置方式;较好的Java代码组织,100%单元测试分支代码覆盖率;代码40KB左右。
Druid:Druid是Java语言中最好的数据库连接池,Druid能够提供强大的监控和扩展功能,是一个可用于大数据实时查询和分析的高容错、高性能的开源分布式系统,尤其是当发生代码部署、机器故障以及其他产品系统遇到宕机等情况时,Druid仍能够保持100%正常运行。主要特色:为分析监控设计;快速的交互式查询;高可用;可扩展;Druid是一个开源项目,源码托管在github上。
主流连接池各项功能对比如下:
3.数据库连接池Spring集成配置与JNDI配置
下面针对每一种连接池的使用方法,在开发中如何配置给出spring集成配置和在tomcat的conf/context.xml文件中配置2种方式,限于篇幅只给出基本参数,详细参数可自行研究。
3.1 阿里Druid连接池
Maven依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.28</version>
</dependency>
Spring集成配置方式
<!--Spring Druid 数据源配置--> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"> <!-- 基本属性 url、user、password --> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> <!-- 配置初始化大小、最小、最大 --> <property name="initialSize" value="1" /> <property name="minIdle" value="1" /> <property name="maxActive" value="20" /> <!-- 配置获取连接等待超时的时间 --> <property name="maxWait" value="60000" /> <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 --> <property name="timeBetweenEvictionRunsMillis" value="60000" /> <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 --> <property name="minEvictableIdleTimeMillis" value="300000" /> <!-- 打开PSCache,并且指定每个连接上PSCache的大小 --> <property name="poolPreparedStatements" value="true" /> <property name="maxPoolPreparedStatementPerConnectionSize" value="20" /> <!-- 配置监控统计拦截的filters,去掉后监控界面sql无法统计 --> <property name="filters" value="stat" /> </bean> Web.xml配置 <!--druid WebStatFilter用于采集web-jdbc关联监控的数据--> <filter> <filter-name>DruidWebStatFilter</filter-name> <filter-class>com.alibaba.druid.support.http.WebStatFilter</filter-class> <init-param> <param-name>exclusions</param-name> <param-value>*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*</param-value> </init-param> </filter> <filter-mapping> <filter-name>DruidWebStatFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!--druid访问监控界面 /druid/index.html--> <servlet> <servlet-name>DruidStatView</servlet-name> <servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>DruidStatView</servlet-name> <url-pattern>/druid/*</url-pattern> </servlet-mapping>
Tomcat中context.xml文件JNDI配置方式
com.alibaba.druid.pool.DruidDataSourceFactory实现了javax.naming.spi.ObjectFactory,可以作为JNDI数据源来配置
<TOMCAT_HOME>/conf/context.xml配置JNDI方式
<Resource name="jdbc/MysqlDataSource" factory="com.alibaba.druid.pool.DruidDataSourceFactory" auth="Container" type="javax.sql.DataSource" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://192.168.1.233:3306/lead_oams?useUnicode=true&characterEncoding=utf-8" username="lead_system" password="password" maxActive="50" maxWait="10000" removeabandoned="true" removeabandonedtimeout="60" logabandoned="false" filters="stat"/>
web.xml配置
<!--MySQL数据库JNDI数据 --> <resource-ref> <description>MySQL DB Connection</description> <res-ref-name>jdbc/MysqlDataSource</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref>
Java代码中获取JNDI数据源
//1、初始化名称查找上下文
Context ctx =new InitialContext();
//2、通过JNDI名称找到DataSource
DruidDataSource ds = (DruidDataSource)ctx.lookup("java:comp/env/jdbc/MysqlDataSource");
//3、通过ds获取数据库连接对象
Connectionconn = ds.getConnection();
3.2 BoneCP连接池
Maven依赖
<dependency>
<groupId>com.jolbox</groupId>
<artifactId>bonecp-spring</artifactId>
<version>0.8.0.RELEASE</version>
</dependency>
Spring集成BoneCP配置方式
<!-- Spring BoneCP 数据源配置--> <bean id="dataSource" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close"> <!-- 数据库驱动 --> <property name="driverClass" value="${jdbc.driver}" /> <!-- 相应驱动的jdbcUrl --> <property name="jdbcUrl" value="${jdbc.url}" /> <!-- 数据库的用户名 --> <property name="username" value="${jdbc.username}" /> <!-- 数据库的密码 --> <property name="password" value="${jdbc.password}" /> <!-- 检查数据库连接池中空闲连接的间隔时间,单位是分,默认值:240,如果要取消则设置为0 --> <property name="idleConnectionTestPeriod" value="60" /> <!-- 连接池中未使用的链接最大存活时间,单位是分,默认值:60,如果要永远存活设置为0 --> <property name="idleMaxAge" value="30" /> <!-- 每个分区最大的连接数 --> <property name="maxConnectionsPerPartition" value="150" /> <!-- 每个分区最小的连接数 --> <property name="minConnectionsPerPartition" value="5" /> </bean>
Tomcat中BoneCP使用JNDI配置方式
<Resource name="JNDIName" auth="Container" type="com.jolbox.bonecp.BoneCPDataSource" factory="org.apache.naming.factory.BeanFactory" driverClass="oracle.jdbc.driver.OracleDriver" username="root" password="root" jdbcUrl="jdbc:mysql://localhost:3306/test" idleConnectionTestPeriod="0" idleMaxAge="10" partitionCount="1" maxConnectionsPerPartition="5" minConnectionsPerPartition="1" connectionTestStatement="" initSQL="select 1 from dual"/>
Java代码中获取JNDI数据源
//1、初始化名称查找上下文
Context ctx =new InitialContext();
//2、通过JNDI名称找到DataSource
DataSource ds= (DataSource) ctx.lookup("java:comp/env/jdbc/MysqlDataSource");
//3、通过ds获取数据库连接对象
Connectionconn = ds.getConnection();
3.3 Tomcat Jdbc Pool连接池
Maven依赖
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId>
<version>7.0.75</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-juli</artifactId>
<version>7.0.75</version>
</dependency>
Spring集成Tomcat Jbdc Pool配置方式
<!--tomcat jdbc pool数据源配置--> <beanid="dataSource"class="org.apache.tomcat.jdbc.pool.DataSource"destroy-method="close"> <propertyname="poolProperties"> <beanclass="org.apache.tomcat.jdbc.pool.PoolProperties"> <!--driverClassName url username password--> <propertyname="driverClassName"value="com.mysql.jdbc.Driver"/> <propertyname="url"value="jdbc:mysql://localhost:3306/test?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8"/> <propertyname="username"value="root"/> <propertyname="password"value="root"/> <!--jmx support--> <propertyname="jmxEnabled"value="true"/> <propertyname="testWhileIdle"value="true"/> <propertyname="testOnBorrow"value="true"/> <propertyname="testOnReturn"value="false"/> <propertyname="validationInterval"value="30000"/> <propertyname="validationQuery"value="SELECT 1"/> <propertyname="timeBetweenEvictionRunsMillis"value="30000"/> <!--最大连接--> <propertyname="maxActive"value="50"/> <!--初始化连接--> <propertyname="initialSize"value="5"/> <!--最长等待时间ms--> <propertyname="maxWait"value="10000"/> <propertyname="minEvictableIdleTimeMillis"value="30000"/> <propertyname="minIdle"value="10"/> <!--是否允许日志--> <propertyname="logAbandoned"value="false"/> <propertyname="removeAbandoned"value="true"/> <propertyname="removeAbandonedTimeout"value="60"/> <propertyname="jdbcInterceptors"value="org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer"/> </bean>
Tomcat中context.xml文件JNDI配置方式
<Resource name="jdbc/test" auth="Container" factory="org.apache.tomcat.jdbc.pool.DataSourceFactory" testWhileIdle="true" testOnBorrow="true" testOnReturn="false" validationQuery="SELECT 1" validationInterval="30000" timeBetweenEvictionRunsMillis="30000" driverClassName="com.mysql.jdbc.Driver" maxActive="100" maxIdle="40" maxWait="12000" initialSize="10" removeAbandonedTimeout="60" removeAbandoned="true" logAbandoned="true" minEvictableIdleTimeMillis="30000" jmxEnabled="true" jdbcInterceptors= "org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer" username="root" password="root" type="javax.sql.DataSource" url="jdbc:mysql://localhost:3306/test?characterEncoding=UTF-8"/>
Java代码中获取JNDI数据源
//1、初始化名称查找上下文
Context ctx =new InitialContext();
//2、通过JNDI名称找到DataSource
DataSource ds= (DataSource) ctx.lookup("java:comp/env/jdbc/test");
//3、通过ds获取数据库连接对象
Connectionconn = ds.getConnection();
3.4 Apache DBCP连接池
Maven依赖
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.2</version>
</dependency>
<dependency>
<groupId>commons-pool</groupId>
<artifactId>commons-pool</artifactId>
<version>1.6</version>
</dependency>
Spring集成DBCP配置方式
<!-- 配置dbcp数据源 --> <bean id="dataSource" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="${jdbc.driverClassName}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> <!-- 池启动时创建的连接数量 --> <property name="initialSize" value="5"/> <!-- 同一时间可以从池分配的最多连接数量。设置为0时表示无限制。 --> <property name="maxActive" value="50"/> <!-- 池里不会被释放的最多空闲连接数量。设置为0时表示无限制。 --> <property name="maxIdle" value="10"/> <!-- 在不新建连接的条件下,池中保持空闲的最少连接数。 --> <property name="minIdle" value="3"/> <!-- 设置自动回收超时连接 --> <property name="removeAbandoned" value="true" /> <!-- 自动回收超时时间(以秒数为单位) --> <property name="removeAbandonedTimeout" value="200"/> <!-- 设置在自动回收超时连接的时候打印连接的超时错误 --> <property name="logAbandoned" value="true"/> <!-- 等待超时以毫秒为单位,在抛出异常之前,池等待连接被回收的最长时间(当没有可用连接时)。设置为-1表示无限等待。--> <property name="maxWait" value="100"/> </bean>
Tomcat中context.xml文件JNDI配置方式
<Resource name="/jdbc/test" type="javax.sql.DataSource" driverClassName="com.sybase.jdbc3.jdbc.SybDataSource" url="jdbc:mysql://localhost:3306/test?characterEncoding=UTF-8" username="root" password="root" initialSize="5" maxActive="50" maxIdle="10" minIdle="3" maxWait="50000" />
Java代码中获取JNDI数据源
//1、初始化名称查找上下文
Context ctx =new InitialContext();
//2、通过JNDI名称找到DataSource
DataSource ds= (DataSource) ctx.lookup("java:comp/env/jdbc/test");
//3、通过ds获取数据库连接对象
Connectionconn = ds.getConnection();
3.5 C3p0连接池
Maven依赖
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
Spring集成配置方式
<!-- Spring配置c3p0数据源 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <property name="jdbcUrl" value="${jdbc.url}" /> <property name="driverClass" value="${jdbc.driverClassName}" /> <property name="user" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> <!--连接池中保留的最大连接数。Default: 15 --> <property name="maxPoolSize" value="100" /> <!--连接池中保留的最小连接数。--> <property name="minPoolSize" value="1" /> <!--初始化时获取的连接数,取值应在minPoolSize与maxPoolSize之间。Default: 3 --> <property name="initialPoolSize" value="10" /> <!--最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 --> <property name="maxIdleTime" value="30" /> <!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 --> <property name="acquireIncrement" value="5" /> <!--JDBC的标准参数,用以控制数据源内加载的PreparedStatements数量。Default: 0--> <property name="maxStatements" value="0" /> <!--每60秒检查所有连接池中的空闲连接。Default: 0 --> <property name="idleConnectionTestPeriod" value="60" /> <!--定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 --> <property name="acquireRetryAttempts" value="30" /> <!--获取连接失败将会引起所有等待连接池来获取连接的线程抛出异常。Default: false--> <property name="breakAfterAcquireFailure" value="true" /> <!--因性能消耗大请只在需要的时候使用它。Default: false --> <property name="testConnectionOnCheckout" value="false" /> </bean>
Tomcat中context.xml文件JNDI配置方式
<Resource name="jdbc/MysqlDataSource" auth="Container" factory="org.apache.naming.factory.BeanFactory" type="com.mchange.v2.c3p0.ComboPooledDataSource" driverClass="com.mysql.jdbc.Driver" idleConnectionTestPeriod="60" maxPoolSize="50" minPoolSize="2" acquireIncrement="2" user="root" password="root" jdbcUrl="jdbc:mysql://localhost:3306/test"/>
Java代码中获取JNDI数据源
//1、初始化名称查找上下文
Context ctx =new InitialContext();
//2、通过JNDI名称找到DataSource
DataSource ds= (DataSource) ctx.lookup("java:comp/env/jdbc/MysqlDataSource");
//3、通过ds获取数据库连接对象
Connectionconn = ds.getConnection();
4.总结
本文所比较的5种数据库连接池在性能方面,根据个人测试结果和参考网上资料Druid > TomcatJDBC > DBCP > C3P0,BoneCP的性能方面没有深入比较,应该和Tomcat Jdbc差不多。对于小型的系统,并发压力不大时,选择哪一种数据库连接池差别不会很大,主要考虑的应该是连接池的稳定性。当并发量较高时,一般不会选择使用DBCP和C3P0,选择Druid是较好的。本文给出了5种数据库连接池通过Spring配置和Tomcat JNDI方式配置两种方式,Spring配置一般使用单独的属性文件,每一个连接池都提供了使用代码创建的方式,使用方式也比较类似,感兴趣可以自行研究。另外连接不同的数据库时,在配置方面的差异主要在driverClass和jdbcUrl两项,优化配置项可以另行考虑。
欢迎大家关注博主订阅号“Java技术日志”,提供Java相关技术分享,从Java编程基础到Java高级技术,从JavaWeb技术基础Jsp、Servlet、JDBC到SSH、SSM开发框架,从REST风格接口设计到分布式项目实战。剖析主流开源技术框架,用亲身实践来谱写深度Java技术日志。
相关推荐
4. **JNDI服务**:Java Naming and Directory Interface用于查找和管理网络资源,常用于Java EE环境中的资源定位,如数据库连接池配置。 5. **过滤器与监听器**:Filter和Listener是Java Web中的两大组件,过滤器...
9. **框架应用**:在实战部分,可能会涉及Spring、MyBatis等主流Java开发框架的使用,这些框架简化了开发流程,提高了开发效率。 10. **项目实战**:书中的案例实战部分通常会包含一个或多个实际项目,如构建Web...
《Java数据库编程宝典》是一本深度探讨Java与数据库交互技术的专业书籍,旨在帮助开发者熟练掌握在Java环境中进行高效数据库编程的各种方法。本书涵盖了从基础的JDBC API使用到高级的ORM框架,如Hibernate和MyBatis...
3. **JDBC与数据库连接**:Java Web应用通常需要与数据库交互,JDBC(Java Database Connectivity)是Java访问数据库的标准API。学习如何创建数据库连接、执行SQL语句、处理结果集,以及事务管理和连接池管理。 4. ...
B、阿里巴巴数据库连接池Druid 性能好的数据库连接池,稳定、可扩展、高性能、高并发 C、安全权限框架Shiro 实现认证、授权、加密、缓存、并发、会话管理、单点登录等功能 D、Ehcache二级缓存和Spring MVC静态...
《Java项目实战大全》是针对Java开发者的一部深度学习与实践指南,涵盖了广泛的Java开发领域,旨在提升读者的项目实施能力和解决实际问题的能力。通过深入理解并应用书中的知识点,开发者能够更好地掌握Java编程,...
了解SQL语句、事务处理、连接池配置以及ORM工具如Hibernate或MyBatis的使用,有助于优化数据操作性能。 七、容器与部署 Tomcat、Jetty等Servlet容器用于运行Java Web应用。学习如何配置、部署应用到这些容器,以及...
高并发复用数据库链接技术详解之数据库连接池 类加载器的高级特性(自定义类加器实现加密解密) iBATIS开源主流框架(实现半自动化hibernate) 企业实用技能之详解(眼睛横纹模式验证码防止恶意登陆) 动态页面的静态化...
在Java项目设计与开发范例中,我们涵盖了Java编程语言在实际项目中的应用,这包括了从需求分析、系统设计、编码实现到测试部署的全...通过这个Java项目设计与开发范例,开发者将有机会实践这些理论知识,提升实战技能。
项目可能使用了关系型数据库MySQL或Oracle,涉及SQL查询优化、事务管理、数据库连接池等知识。 4. **MVC架构**:模型-视图-控制器架构在该项目中被广泛运用,以分离业务逻辑、数据处理和用户界面。这有助于提高代码...
- JDBC基础:教授如何使用Java连接和操作数据库,包括连接池管理。 - ORM框架:如Hibernate或MyBatis的使用,简化数据库操作。 5. **模块21:前端技术** - HTML/CSS/JavaScript:基础的前端页面构建技术,用于...
- **连接池配置**:数据库连接池可以有效减少连接数据库的时间开销,教程将指导如何配置HikariCP等高性能的连接池。 #### 八、部署与发布 - **打包成可执行文件**:教程会详细介绍如何使用Maven或Gradle将Spring ...
同时,了解如何在Java程序中连接和操作MySQL数据库,包括JDBC驱动的引入和数据库连接池的使用。 5. **SSH框架搭建**: - **Struts**:Struts作为MVC(模型-视图-控制器)框架的一部分,负责处理HTTP请求,调度控制...
9. **数据库知识**:SQL查询语句的编写,索引优化,事务隔离级别,数据库连接池(如C3P0、HikariCP)等,对于Java开发者来说非常重要。 10. **网络编程**:TCP/IP协议、HTTP协议的理解,Socket编程,以及RESTful ...
- 学习数据库连接池的使用,如C3P0、Apache DBCP或HikariCP,提高数据库操作效率。 6. **Spring框架**: - Spring是Java企业级应用的主流框架,包含IOC(Inversion of Control)和AOP(Aspect Oriented ...
1. **J2EE**:Java EE是企业级应用开发的标准,提供了服务器端组件模型、事务管理、安全性和数据库连接池等功能。在Java Web开发中,J2EE提供了一个统一的平台,使得开发者可以构建可扩展且健壮的应用。 2. **...
在Java项目实战练习中,我们通常会涉及到许多关键知识点,这些知识涵盖了软件开发的各个方面,包括但不限于编程基础、设计模式、框架应用、数据库交互、异常处理、多线程以及单元测试等。以下是对这些核心概念的详细...
需要掌握SQL查询语句、连接池管理和事务处理。 5. **JSTL与EL表达式**:为了减少JSP页面上的Java代码,通常会使用JSTL(JavaServer Pages Standard Tag Library)和EL(Expression Language)。JSTL提供了一系列...
5. **数据库连接池配置**: - 使用C3P0或Druid作为数据库连接池,提高数据库访问效率。 #### 三、Controller与Service层设计 1. **Controller设计原则**: - 单一职责原则:每个Controller只负责一个特定的功能...