目录在前面写过 Java 如何简单的连接数据库的,通过 DriverManager 获得连接,但是实际上很少用,因为效率低,使用连接池可以将程序性能大幅提升
一、数据库连接池的原理
当使用数据库的时候,需要先连接数据库,原始的连接方式是:通过 DriverManager 获得连接,一个数据库连接对象都对应一个物理数据库连接,每次操作数据库都会打开一个物理连接,使用完再关闭,频繁的打开、关闭,会造成系统性能低,如图所示:
那么我们该如何解决使用数据库时,频繁的打开和关闭数据库连接所造成的效率低下呢?
数据库连接池是这样解决的:
当应用程序启动时,系统主动建立足够的数据库连接,并将这些连接组成一个池,每次使用的时候,就不用重新打开连接,直接从连接池里拿出已有的连接用,用完了,也不用关闭,返回连接池就好了。使用连接池,程序运行的效率有很大的提升。
二、数据库连接池的使用
JDBC的 数据库连接池使用 Javax.sql.DataSource 来表示,DataSource只是一个接口,有商用服务器等提供实现,也有比较常用的开源组织提供实现(比如DBCP、C3P0),DataSource通常被称为数据源,包含连接池和连接池管理,但习惯也把 DataSource 称为连接池
1. DBCP数据源
该连接池实现需要依赖两个 jar 包,所有第一步,需要先增加 jar 包:
使用DBCP数据源来获得数据库连接方式:
//创建数据源对象
BasicDataSource bds = new BasicDataSource();
//设置连接池所需的驱动
bds.setDriverClassName("com.mysql.jdbc.Driver");
//设置连接数据库的URL
bds.setUrl("jdbc:mysql://localhost:3306/csdn");
//设置连接数据库的用户名
bds.setUsername("root");
//设置连接数据库的密码
bds.setPassword("root");
//设置连接池的初始连接数
bds.setInitialSize(5);
//设置连接池最多有多少个活动的连接数
bds.setMaxActive(20);
//设置连接池中最多有多少空闲的连接
bds.setMinIdle(2);
注意:整个应用只要一个数据源就可以了,也就是说上面代码只执行一次
优化:可以把上面的 bds 设置成 static 成员变量,并在应用开始的时候,就初始化数据源对象,程序中有需要获得数据库连接的时候,直接访问 bds 对象,并且获得数据库连接
再通过 DataSource 获取数据库的连接:
//通过数据源获得数据库的连接
Connection con = bds.getConnection();
......
//释放连接
con.close();
2. C3P0数据源
和前面的 DBCP 数据源相比,C3P0数据源性能更好,推荐使用,因为 C3P0 可以自动清理不再使用的 Connection ,还可以自动清理 Statement 和 ResultSet。
同样的,如果使用 C3P0 连接池,需要增加的 jar 包:c3p0-0.9.1.2.jar
使用 C3P0 数据源来获得数据库连接方式:
//创建连接池实例
ComboPooleDataSource cds = new ComboPooleDataSource();
//设置连接池所需的驱动
cds.setDriverClass("com.mysql.jdbc.Driver");
//设置连接数据库的URL
cds.setjdbcUrl("jdbc:mysql://localhost:3306/csdn");
//设置连接数据库的用户名
cds.setUser("root");
//设置连接数据库的密码
cds.setPassword("root");
//设置连接池的初始连接数
cds.setInitialPoolSize(20);
//设置最大连接数
cds.setMaxPoolSize(30);
//设置最小连接数
cds.setMinPoolSize(3);
//设置连接池里的缓存 Statement 的最大数
cds.setMaxStatement(150);
创建 C3P0 连接池的方式和前面创建 DBCP连接池的方法基本类似,在获得了 C3P0 连接池之后,同样的再获得数据库的连接:
//获得数据库的连接
Connection con = cds.getConnection();
//同样的释放连接
con.close();
注意:此时,虽然释放了数据库连接,但是并没有关闭数据库的物理连接,仅仅是把连接释放,释放到连接池,其他用户还可以使用该连接。