Java 数据库连接池详解及简单实例
这里有新鲜出炉的 Java 函数式编程, 程序狗速度看过来!
Java 程序设计语言
java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言, 是由 Sun Microsystems 公司于 1995 年 5 月推出的 Java 程序设计语言和 Java 平台 (即 JavaEE(j2ee), JavaME(j2me), JavaSE(j2se)) 的总称
这篇文章主要介绍了 Java 数据库连接池详解及简单实例的相关资料, 需要的朋友可以参考下
Java 数据库连接池详解
数据库连接池的原理是:
连接池基本的思想是在系统初始化的时候, 将数据库连接作为对象存储在内存中, 当用户需要访问数据库时, 并非建立一个新的连接, 而是从连接池中取出一个已建立的空闲连接对象使用完毕后, 用户也并非将连接关闭, 而是将连接放回连接池中, 以供下一个请求访问使用而连接的建立断开都由连接池自身来管理同时, 还可以通过设置连接池的参数来控制连接池中的初始连接数连接的上下限数以及每个连接的最大使用次数最大空闲时间等等也可以通过其自身的管理机制来监视数据库连接的数量使用情况等
常用的数据库连接池:
常用的数据库连接池有 JNDI,C3p0,Apache 的 Jakarta 和 DBCPBoneCP 其中, sping 框架依赖的第三方使用了 c3p0 和 dbcp 两种方式; 而 bonecp 号称是速度最快的数据库连接池 JNDI 方式创建实现的 datasource 是真正实现了 javax.sql.datasource(其他的三种方式都不是)
现在我们主要来介绍如何使用 JNDI 方式, 这种方式, 是由 web 服务器 (例如: tomcat,weblogic,websphere,tomcat), 实现了 java.sql.datasource 由 web 服务器负责初始化数据源, 创建 connection, 分配, 管理 connection 由于本身是由 web 服务器实现的功能, 因此不需要在项目中引入特别的 jar 包, 但是需要在服务器的某些配置文件中增加相关的配置下面, 以 Tomcat 服务器(数据库为 MySQL) 为例, 讲述这种方式的使用
数据库的创建与初始化数据:
- create table test(id INT PRIMARY KEY,name VARCHAR(10),price FLOAT)
- INSERT INTO test VALUES(1,'English',22.2);
- INSERT INTO test VALUES(2,'Math',78.9);
- INSERT INTO test VALUES(3,'History',77.9);
1. 将 数据驱动 mysql-connector-java-5.0.3-bin.jar 放入 tomcat 目录下的 lib 中
2. 修改 tomcat 的 conf 下的 context.xml 文件, 增加 Resource 的配置的支持
- <Resource auth="Container" driverClassName="com.mysql.jdbc.Driver" maxActive="100"
- maxIdle="30" maxWait="10000" name="jdbc/ewsdb" username="root" password="admin"
- type="javax.sql.DataSource" url="jdbc:mysql://localhost:3306/test1" />
<Resource 属性说明>
1)name: 指定 Resource 的 JNDI 名字
2)auth: 指定管理 Resource 的 Manager, 它有两个可选值: Container 和 ApplicationContainer 表示由容器来创建和管理 Resource,Application 表示由 web 应用来创建和管理 Resource
3)type: 指定 Resource 的 Java 类名
4)username: 指定连接数据库的用户名
5)password: 指定连接数据库的口令
6)driverClassName: 指定连接数据库的 JDBC 驱动器中的 Driver 实现类的名字
7)url: 指定连接数据库的 URL,127.0.0.1 是要连接的数据库服务器的 ip,3306 是数据库服务器端口, BookDB 是数据库名称
8)maxActive: 指定数据库连接池中处于活动状态的数据库连接的最大数目, 取值为 0, 表示不受限制
9)maxIdle: 指定数据库连接池中处于空闲状态的数据库连接的最大数目, 取值为 0, 表示不受限制
10)maxWait: 指定数据库连接池中的数据库连接处于空闲状态的最长时间(以毫秒为单位), 超过这一时间, 将会抛出异常取值为 - 1, 表示可以无限期等待
maxActive="100"
表示并发情况下最大可从连接池中获取的连接数如果数据库不是单独, 供一个应用使用, 通过设置 maxActive 参数可以避免某个应用无限制的获取连接对其他应用造成影响, 如果一个数据库只是用来支持一个应用那么 maxActive 理论上可以设置成该数据库可以支撑的最大连接数 maxActive 只是表示通过连接池可以并发的获取的最大连接数连接的获取与释放是双向, 当应用程序并发请求连接池时, 连接池就需要从数据库获取连接, 那么但应用程序使用完连接并将连接归还给连接池时, 连接池是否也同时将连接归还给数据库呢? 很显然答案是否定的, 如果那样的话连接池就变得多此一举, 不但不能提高性能, 反而会降低性能, 那么但应用成归还连接后, 连接池如何处理呢?
maxIdle="30"
如果在并发时达到了 maxActive=100, 那么连接池就必须从数据库中获取 100 个连接来供应用程序使用, 当应用程序关闭连接后, 由于 maxIdle=30, 因此并不是所有的连接都会归还给数据库, 将会有 30 个连接保持在连接池种中, 状态为空闲
minIdle=2
最小默认情况下并不生效, 它的含义是当连接池中的连接少有 minIdle, 系统监控线程将启动补充功能, 一般情况下我们并不启动补充线程
问题: 如何设置 maxActive 和 maxIdle?
理论上讲 maxActive 应该设置成应用的最大并发数, 这样一来即便是在最大并发的情况下, 应用依然能够从连接池中获取连接, 但是困难时的是我们很难准确估计到最大并发数, 设置成最大并发数是一种最优的服务质量保证
maxIdle 对应的连接, 实际上是连接池保持的长连接, 这也是连接池发挥优势的部分, 理论上讲保持较多的长连接, 在应用请求时可以更快的响应, 但是过多的连接保持, 反而会消耗数据库大量的资源, 因此 maxIdle 也并不是越大越好, 同上例我们建议将 maxIdle 设置成 50-100 中靠近 50 的数字, 例如 55 这样就能在兼顾最大并发同时, 保持较少的数据库连接, 而且在绝大多情况, 能够为应用程序提供最快的相应速度
3.打开应用程序的 Web.xml 文件, 添加以下配置
- <resource-ref>
- <description>DB Connection</description>
- <res-ref-name>jdbc/ewsdb</res-ref-name>
- <res-type>javax.sql.DataSource</res-type>
- <res-auth>Container</res-auth>
- </resource-ref>
<resource-ref > 属性说明:
1)description: 对所引用的资源的说明
2)res-ref-name: 指定所引用资源的 JNDI 名字, 与 < Resource > 元素中的 name 属性对应
3)res-type: 指定所引用资源的类名, 与 < Resource > 元素中的 type 属性对应
4)res-auth: 指定管理所引用资源的 Manager, 与 < Resource > 元素中的 auth 属性对应
4. 编写使用 java 代码, 并放在 tomcat 环境下使用, 如下
创建 JSP 范例: MyJsp.jsp
- <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
- <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
- <%@ page import="java.io.*" %>
- <%@ page import="java.util.*" %>
- <%@ page import="java.sql.*" %>
- <%@ page import="javax.sql.*" %>
- <%@ page import="javax.naming.*" %>
- <html>
- <head>
- <title>Tomcat 下 JNDI 数据库连接池</title>
- </head>
- <body>
- <%
- try{
- Connection conn;
- Statement stmt;
- ResultSet rs;
- Context ctx = new InitialContext();
- DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/ewsdb");
- conn = ds.getConnection();
- stmt = conn.createStatement();
- // 查询记录
- rs = stmt.executeQuery("select ID,NAME,PRICE from test");
- // 输出查询结果
- out.println("<table border=1 width=400>");
- while (rs.next()){
- String col1 = rs.getString(1);
- String col2 = rs.getString(2);
- float col3 = rs.getFloat(3);
- // 打印显示的数据
- out.println("<tr><td>"+col1+"</td><td>"+col2+"</td><td>"+col3+"</td></tr>");}
- out.println("</table>");
- // 关闭结果集 SQL 声明和数据库连接
- rs.close();
- stmt.close();
- conn.close();
- }catch(Exception e){
- out.println(e.getMessage());
- e.printStackTrace();
- }
- %>
- </body>
- </html>
在浏览器中输入 http://localhost:8080/test/MyJsp.jsp, 即可查看结果
来源: http://www.phperz.com/article/18/0207/359076.html