打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
数据库连接池的应用与研究
          对Java初学者来说,数据库连接池同其它的XX池一样,看起来是很神秘的一种技术,其实都是难者不会,会者不难的情况。当了解了数据库连接池技术之后,数据库连接池并不神秘而是一个非常简单的小技巧。
      为什么会有数据库连接池呢?对于一个系统来说,如果没有数据库连接,当你每次需要进行数据库操作时,都要获取连接,完成操作之后将连接关闭。当系统访问量上来之后,你就会发现系统将会有大量的实践都花在获取数据库连接和关闭连接上。因此如果我们建立一个数据库连接池,在系统启动时,一次性的获取若干条数据库连接加入到连接池中,当我们需要进行数据库操作时,直接从数据库连接池中拿到连接,用完之后不再关闭,而是将其放入连接池中,这样系统运行时将再不会有频繁的获取连接和关闭连接了。下面,我们就自己写一个简单的数据库连接池,并加以测试。
      1. ConnectionPool类:数据库连接池类. 运用单例模式,当要进行数据库操作时,先调用ConnectionPool.getInstance()方法,获取数据库连接池的实例,然后调用connectionPool.getConnection()方法获取数据库连接,使用完连接之后调用connectionPool.release(Connection conn)来代替connection.close()方法来将获得的连接释放到连接池中,以便重复利用。这样就解决了频繁打开和关闭数据库连接池的问题。
       ConnectionPool.java
Java代码 
  1. public class ConnectionPool {  
  2.       
  3.     private List<Connection> connections ;  
  4.     private int poolSize = 1;//  
  5.     private String url;  
  6.     private String username;  
  7.     private String password;  
  8.     private String driverClassName;  
  9.       
  10.     private static ConnectionPool instance = null;  
  11.       
  12.     private ConnectionPool() {  
  13.         initialize();  
  14.     }  
  15.       
  16.     /** 
  17.      * 初始化方法 
  18.      */  
  19.     private void initialize() {  
  20.         connections = new ArrayList<Connection>(poolSize);  
  21.         readConfig();  
  22.         addConnection();  
  23.     }  
  24.       
  25.     /** 
  26.      * 读取数据库连接池的配置文件 
  27.      */  
  28.     private void readConfig() {  
  29.         String path = System.getProperty("user.dir")+"/resources/config/jdbc.properties";  
  30.         try {  
  31.             FileInputStream is = new FileInputStream(path);  
  32.             Properties prop = new Properties();  
  33.             prop.load(is);  
  34.             driverClassName = prop.getProperty("jdbc.driverClassName");  
  35.             url = prop.getProperty("jdbc.url");  
  36.             username = prop.getProperty("jdbc.username");  
  37.             password = prop.getProperty("jdbc.password");  
  38.             poolSize = Integer.parseInt(prop.getProperty("jdbc.poolSize"));  
  39.         } catch (Exception e) {  
  40.             e.printStackTrace();  
  41.         }  
  42.     }  
  43.       
  44.     /** 
  45.      * 往数据库连接池中添加连接 
  46.      */  
  47.     private void addConnection() {  
  48.         for (int i=0; i < poolSize; i++) {  
  49.             try {  
  50.                 Class.forName(driverClassName);  
  51.                 Connection connection = java.sql.DriverManager.getConnection(url, username, password);  
  52.                 connections.add(connection);  
  53.             } catch (ClassNotFoundException e) {  
  54.                 e.printStackTrace();  
  55.             } catch (SQLException e) {  
  56.                 e.printStackTrace();  
  57.             }  
  58.         }  
  59.     }  
  60.       
  61.     /** 
  62.      * 获取数据库连接池 
  63.      * @return 
  64.      */  
  65.     public static ConnectionPool getConnectionPoolInstance() {  
  66.         if (instance == null) instance = new ConnectionPool();  
  67.         return instance;  
  68.     }  
  69.       
  70.     /** 
  71.      * 从数据库连接池中获取数据库连接 
  72.      * @return 
  73.      */  
  74.     public synchronized Connection getConnection() {  
  75.         if (connections.size() <= 0) return null;  
  76.         Connection connection = connections.get(0);  
  77.         connections.remove(0);  
  78.         return connection;  
  79.     }  
  80.       
  81.     /** 
  82.      * 释放数据库连接 
  83.      * 使用完数据库连接池之后调用这个方法来代替close方法 
  84.      * @param connection 
  85.      */  
  86.     public synchronized void realase(Connection connection) {  
  87.         connections.add(connection);  
  88.     }  
  89.       
  90.     /** 
  91.      *  关闭数据库连接池 
  92.      */  
  93.     public synchronized void closePool() {  
  94.         for (int i =0; i < connections.size(); i++) {  
  95.             Connection connection = connections.get(i);  
  96.             try {  
  97.                 connection.close();  
  98.             } catch (SQLException e) {  
  99.                 e.printStackTrace();  
  100.             }  
  101.             connections.remove(i);  
  102.         }  
  103.     }  
  104. }  

          2.  jdbc.propeties  数据库连接池配置文件,初始化数据库连接池时使用到。
          
Xml代码 
  1. jdbc.driverClassName=oracle.jdbc.xa.client.OracleXADataSource  
  2. jdbcjdbc.url=jdbc:oracle:thin:@127.0.0.1:1521:mgodb  
  3. jdbc.username=CAR  
  4. jdbc.password=CAR  
  5. jdbc.poolSize=10  


         3. ConnectionPoolTest类: 测试类,  通过与不使用数据库连接池进行数据库访问所消耗的时间进行对比,为了使测试尽可能准确,通过100次循环调用,对比时间总和。
          ConnectionPoolTest.java
Java代码 
  1. public class ConnectionPoolTest extends TestCase {  
  2.   
  3.     public void testConnectionPoolTest() throws Exception {  
  4.         String sql = "SELECT * FROM T_CR_CAR_TYPE_BRAND";  
  5.         ConnectionPool connectionPool = null;  
  6.         long starttime = System.currentTimeMillis();  
  7.         for (int i = 0; i < 100; i++) {  
  8.             connectionPool = ConnectionPool.getConnectionPoolInstance();  
  9.             Connection conn = connectionPool.getConnection();  
  10.             ResultSet rs;  
  11.             Statement stmt = conn.createStatement();  
  12.             rs = stmt.executeQuery(sql);  
  13.             while (rs.next()) {  
  14.             }  
  15.             rs.close();  
  16.             stmt.close();  
  17.             rs = null;  
  18.             stmt = null;  
  19.             connectionPool.realase(conn);  
  20.         }  
  21.         connectionPool.closePool();  
  22.         System.out.println("经过100次循环调用,使用连接池花费的时间:"  
  23.                 + (System.currentTimeMillis() - starttime) + "ms\n");  
  24.   
  25.         String driverClassName = "oracle.jdbc.xa.client.OracleXADataSource";  
  26.         String url = "jdbc:oracle:thin:@127.0.0.1:1521:mgodb";  
  27.         String username = "CAR";  
  28.         String password = "CAR";  
  29.         starttime = System.currentTimeMillis();  
  30.         for (int i = 0; i < 100; i++) {  
  31.             Class.forName(driverClassName);  
  32.             Connection conn = DriverManager.getConnection(url, username,  
  33.                     password);  
  34.             Statement stmt = conn.createStatement();  
  35.             ResultSet rs = stmt.executeQuery(sql);  
  36.             while (rs.next()) {  
  37.             }  
  38.             rs.close();  
  39.             stmt.close();  
  40.             conn.close();  
  41.             rs = null;  
  42.             stmt = null;  
  43.             conn = null;  
  44.         }  
  45.         System.out.println("经过100次循环调用,不使用连接池花费的时间:" + (System.currentTimeMillis() - starttime) + "ms\n");  
  46.     }  
  47. }  

          通过测试结果可以发现,使用数据库连接池所消耗的实践要小于不使用数据库连接池的,当调用的次数增加时,差异将会更加明显。
          当然这个数据库连接池仅仅是用来了解数据库连接池的原理而已,对于超时的连接并没有强制收回的机制,也没有限制用户调用close方法来关闭连接。仅供学习。。。。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
数据库连接池极简教程
有效发挥数据库的最大效率
关ORACLE Cursor的问题ORA-01000: maximum open cursors exceeded
DB2的连接
JNDI与JDBC比较以及连接池的技术 - Do-websoftware - 博客园
Java的JDBC操作
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服