1、原生JDBC的弊端
数据库连接的建立都是对应一个tcp/ip连接建立的过程,故频繁的对数据库进行连接与释放操作是极耗费系统资源的操作。在数据库的连接中使用connection对象,一个数据库连接对象均对应一个物理数据库连接,每次操作都打开一个物理连接,使用完后立即关闭连接。频繁的打开、关闭连接将造成系统性能低下。
2、数据库连接池的工作原理
当应用程序启动并进行数据库连接操作时,系统主动建立足够的数据库连接,并将这些连接组成一个连接池。每当有程序(线程)请求数据库连接时,无须重新打开连接,而是从连接池中取出已有的连接使用,使用完后不再不安比数据库连接,而是直接将连接归还连接池。通过使用连接池,将大大提高程序的运行效率。
3、数据库连接池的使用
3、1配置
- 数据库的初始连接数
- 连接池的最大连接数
- 连接池的最小连接数
3、2步骤代码
static BasicDataSource ds=null;
static {
ds=new BasicDataSource();
//设置连接池所需要的驱动
ds.setDriverClassName("oracle.jdbc.driver.OracleDriver");
//设置连接数据库的url,用户名,密码
ds.setUrl("jdbc:oracle:thin:@127.0.0.1:1521:orcl");
ds.setUsername("scott");
ds.setPassword("252438");
//设置初始连接池大小,最大连接数大小,以及最小连接数大小
ds.setInitialSize(2);
ds.setMaxActive(5);
ds.setMinIdle(2);
}
4、实验分析
1、在数据库连接对象没有超过连接池中最大连接数的数量的情况下
代码:
MyThread myThread=new MyThread();
Thread thread1=new Thread(myThread);
Thread thread2=new Thread(myThread);
Thread thread3=new Thread(myThread);
Thread thread4=new Thread(myThread);
thread1.start();
thread2.start();
thread3.start();
thread4.start();
结果:
这个时候四个线程并发访问数据库,所显示的记录为cpu随机产生处理的结果。
2、 2在数据库连接对象超过连接池中最大连接数的数量的情况下,存在一个等待线程使用完Connect对象并进行重新取回的一个过程
代码:
MyThread myThread=new MyThread();
Thread thread1=new Thread(myThread);
Thread thread2=new Thread(myThread);
Thread thread3=new Thread(myThread);
Thread thread4=new Thread(myThread);
Thread thread5=new Thread(myThread);
Thread thread6=new Thread(myThread);
Thread thread7=new Thread(myThread);
Thread thread8=new Thread(myThread);
thread1.start();
thread2.start();
thread3.start();
thread4.start();
thread5.start();
thread6.start();
thread7.start();
thread8.start();
System.out.println("Main");
结果展示:
从上面的截图可以清晰的看出,在数据库连接池够用的情况下(前十条记录)随机处理一批,而最后的的3个线程要等待前面的线程使用完Connection对象释放以后才可以得以执行。
5、附源码:
DBCPUtil.java
package com.jz.util;
import java.sql.Connection;
import java.sql.SQLException;
import org.apache.commons.dbcp.BasicDataSource;
public class DBCPUtil {
static BasicDataSource ds=null;
static {
ds=new BasicDataSource();
//设置连接池所需要的驱动
ds.setDriverClassName("oracle.jdbc.driver.OracleDriver");
//设置连接数据库的url,用户名,密码
ds.setUrl("jdbc:oracle:thin:@127.0.0.1:1521:orcl");
ds.setUsername("scott");
ds.setPassword("252438");
//设置初始连接池大小,最大连接数大小,以及最小连接数大小
ds.setInitialSize(2);
ds.setMaxActive(5);
ds.setMinIdle(2);
}
public static Connection getConnection() throws SQLException {
return ds.getConnection();
}
}
MyThread.java
package com.jz.thread;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import com.jz.util.DBCPUtil;
public class MyThread implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub
Connection conn=null;
try {
conn=DBCPUtil.getConnection();
PreparedStatement prepareStatement = conn.prepareStatement("select * from myuser");
ResultSet rs = prepareStatement.executeQuery();
String ThreadName=Thread.currentThread().getName();
while(rs.next()) {
int id = rs.getInt(1);
String name = rs.getString(2);
System.out.println(ThreadName+"\t"+id+"\t"+name);
}
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Test
package com.jz;
import com.jz.thread.MyThread;
public class TestDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
MyThread myThread=new MyThread();
Thread thread1=new Thread(myThread);
Thread thread2=new Thread(myThread);
Thread thread3=new Thread(myThread);
Thread thread4=new Thread(myThread);
Thread thread5=new Thread(myThread);
Thread thread6=new Thread(myThread);
Thread thread7=new Thread(myThread);
Thread thread8=new Thread(myThread);
thread1.start();
thread2.start();
thread3.start();
thread4.start();
thread5.start();
thread6.start();
thread7.start();
thread8.start();
System.out.println("Main");
}
}