关闭

Java:自定义数据库连接池

发表于:2013-3-26 09:36

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:ztfriend    来源:51Testing软件测试网采编

  连接池是非常好的想法,应用很普遍。自己写一个数据库连接池,并不像想象中那样困难。一般系统对连接池的功能不会有太多要求,使用自己的连接池未必是个坏主意。下面以Oracle为例,但是对Teradata和Greenplum也是可行的。另外我还实现了连接有效性检查(checkConn)和恢复连接(resetConn)的方法。本例编程采用的是JRE1.4.2环境(别忘了准备访问数据库的jar包)。有任何问题请随时留言,欢迎探讨。

  在Oracle内创建测试数据:

  1. drop table my_table;  
  2. create table my_table(  
  3.        field_id varchar2(3),  
  4.        field_content varchar2(60),  
  5.        record_create_date date default sysdate  
  6. );  
  7. insert into my_table(field_id,field_content) values('001','this is first record');  
  8. insert into my_table(field_id,field_content) values('002','this is second record');  
  9. insert into my_table(field_id,field_content) values('003','this is third record');  
  10. commit;

  DBPool.java:

  1. package dataWebService;  
  2. import java.sql.DriverManager;  
  3. import java.util.Date;  
  4. import java.sql.Connection;  
  5. import java.sql.SQLException;  
  6. import java.sql.Statement;  
  7. public class DBPool{  
  8.     private String cls;  
  9.     private String url;  
  10.     private String usr;  
  11.     private String pss;   
  12.     private int connCount = 3;//连接数 
  13.     private Connection[] connections;//保存数据库连接 
  14.     private String[] connStatus;// 已连可用Y   已连不可用N   未连接X 
  15.     private Date[] lastQueryTime;//时间戳 
  16.       
  17.     public DBPool(DBPoolConfiguration poolConfiguration){  
  18.         this.connCount=poolConfiguration.getConnCount();  
  19.         this.cls=poolConfiguration.getCls();  
  20.         this.url=poolConfiguration.getUrl();  
  21.         this.usr=poolConfiguration.getUsr();  
  22.         this.pss=poolConfiguration.getPss();  
  23.         this.connections=new Connection[this.connCount];  
  24.         this.connStatus=new String[this.connCount];  
  25.         for(int i=0;i<this.connCount;i++){  
  26.             this.connStatus[i]="X";//初始化全部未连接 
  27.         }  
  28.         this.lastQueryTime = new Date[this.connCount];        
  29.     }  
  30.       
  31.     public DBPool(String cls,String url,String usr,String pss){  
  32.         this.cls=cls;  
  33.         this.url=url;  
  34.         this.usr=usr;  
  35.         this.pss=pss;  
  36.         this.connections=new Connection[this.connCount];  
  37.         this.connStatus=new String[this.connCount];  
  38.         for(int i=0;i<this.connCount;i++){  
  39.             this.connStatus[i]="X";//初始化全部未连接 
  40.         }  
  41.         this.lastQueryTime = new Date[this.connCount];  
  42.     }  
  43.     public void initPool(){  
  44.         if(connCount<1){  
  45.             System.out.println("请正确设置连接池窗口个数");  
  46.         }else{  
  47.             try{  
  48.                 Class.forName(this.cls);//register class 
  49.             }catch(ClassNotFoundException e){  
  50.                 System.out.println(e.getMessage());  
  51.             }catch(Exception e){  
  52.                 System.out.println(e.getMessage());//other exceptions 
  53.             }  
  54.             for(int i=0;i<this.connCount;i++){  
  55.                 try{  
  56.                     this.connections[i]=DriverManager.getConnection(this.url, this.usr, this.pss);  
  57.                     this.connStatus[i]="Y";  
  58.                 }catch(SQLException e){  
  59.                     System.out.println(e.getMessage());  
  60.                 }catch(Exception e){  
  61.                     System.out.println(e.getMessage());//other exceptions 
  62.                 }  
  63.             }     
  64.             System.out.println("initPool is ready...");  
  65.         }//end if 
  66.     }  
  67.     public void freePool(){  
  68.         for(int i=0;i<this.connCount;i++){  
  69.             try{  
  70.                 this.connections[i].commit();  
  71.                 this.connections[i].close();  
  72.                 this.connStatus[i]="X";  
  73.                 this.lastQueryTime[i]=null;  
  74.             }catch(Exception e){  
  75.                 try{  
  76.                     this.connections[i].close();  
  77.                     this.connStatus[i]="X";  
  78.                     this.lastQueryTime[i]=null;                   
  79.                 }catch(Exception e1){  
  80.                     System.out.println(e1.getMessage());//just for catch 
  81.                 }  
  82.             }             
  83.         }  
  84.         System.out.println("freePool is over ...");  
  85.     }  
  86.     public DBPoolConnection getPoolConn() throws DBPoolIsFullException{  
  87.         DBPoolConnection poolConnection = new DBPoolConnection();  
  88.         poolConnection.connNbr=getConnNbr();  
  89.         if(poolConnection.connNbr==-1){  
  90.             throw new DBPoolIsFullException("连接池已满");  
  91.         }else{  
  92.             poolConnection.conn=getConn(poolConnection.connNbr);  
  93.         }  
  94.         return poolConnection;  
  95.     }  
  96.     public void freePoolConn(DBPoolConnection poolConnection){  
  97.         if(poolConnection==null){  
  98.             System.out.println("poolConnection==null,不需要释放");  
  99.         }else{  
  100.             freeConn(poolConnection.connNbr);  
  101.         }  
  102.     }  
  103.       
  104.     public void printPoolStatus(){  
  105.         for(int i=0;i<this.connStatus.length;i++){  
  106.             System.out.println("");  
  107.             System.out.print(this.connStatus[i].toString());  
  108.             if(this.lastQueryTime[i]==null){  
  109.                 System.out.print("-[null] ");  
  110.             }else{  
  111.                 System.out.print("-["+this.lastQueryTime[i].toString()+"] ");  
  112.             }  
  113.         }  
  114.         System.out.println("");  
  115.     }  
  116.       
  117.     public String getCls(){  
  118.         return this.cls;  
  119.     }  
  120.     public String getUrl(){  
  121.         return this.url;  
  122.     }  
  123.     public String getUsr(){  
  124.         return this.usr;  
  125.     }  
  126.     int getConnNbr(){  
  127.         int iConn=-1;  
  128.         for(int i=0;i<this.connCount;i++){  
  129.             if(this.connStatus[i].equals("Y")){  
  130.                 this.lastQueryTime[i]=new Date();  
  131.                 this.connStatus[i]="N";  
  132.                 iConn=i;  
  133.                 break;  
  134.             }  
  135.         }  
  136.         return iConn;  
  137.     }  
  138.       
  139.     Connection getConn(int i){  
  140.         return this.connections[i];  
  141.     }  
  142.           
  143.     void closeConnForTest(DBPoolConnection poolConnection){  
  144.         try{  
  145.             this.connections[poolConnection.connNbr].close();  
  146.         }catch(SQLException e){  
  147.             System.out.println(e.getMessage());   
  148.         }  
  149.     }  
  150.           
  151.     boolean checkConn(DBPoolConnection poolConnection){  
  152.         Statement stmt=null;  
  153.         String checkMessage="";  
  154.         boolean checkResult=true;  
  155.           
  156.         //检查连接是否有效 
  157.         try{  
  158.             String sql = "select * from dual";  
  159.             stmt = this.connections[poolConnection.connNbr].createStatement();  
  160.             stmt.executeQuery(sql);//execute sql 
  161.             stmt.close();  
  162.             checkMessage = "checkConn:checkMessage:execute sql success";  
  163.             System.out.println(checkMessage);  
  164.         }catch(Exception e){  
  165.             checkMessage = e.getMessage();  
  166.             System.out.println(e.getMessage());//other exceptions 
  167.             if(checkMessage==null){  
  168.                 checkMessage="e.getMessage() is null";  
  169.                 System.out.println(checkMessage);  
  170.             }  
  171.             //采取激进重连的策略,尽量避免业务中断 
  172.             if (checkMessage.indexOf("ORA-00942")>=0){  
  173.                 checkResult=true;//不需要重连 
  174.             }else if(checkMessage.indexOf("does not exist")>=0){  
  175.                 checkResult=true;//不需要重连 
  176.             }else if(checkMessage.indexOf("Syntax error")>=0){  
  177.                 checkResult=true;//不需要重连 
  178.             }else{            
  179.                 checkResult=false;//需要重连 
  180.             }  
  181.         }  
  182.         return checkResult;  
  183.     }  
  184.       
  185.     boolean resetConn(DBPoolConnection poolConnection){  
  186.         boolean result=false;//默认不需要重建连接  
  187.           
  188.         if(poolConnection==null){  
  189.             System.out.println("poolConnection==null,不知道您想重设哪个连接");  
  190.         }else if(poolConnection.connNbr==-1){  
  191.             System.out.println("poolConnection.connNbr==-1,不知道您想重设哪个连接");  
  192.         }else{  
  193.             if(checkConn(poolConnection)==true){  
  194.                 System.out.println("连接有效,不需要重设");  
  195.             }else{  
  196.                 //重设连接 
  197.                 try{  
  198.                     Class.forName(this.cls);//register class 
  199.                 }catch(ClassNotFoundException e){  
  200.                     System.out.println(e.getMessage());  
  201.                 }catch(Exception e){  
  202.                     System.out.println(e.getMessage());//other exceptions 
  203.                 }  
  204.                 try{  
  205.                     this.connections[poolConnection.connNbr]=DriverManager.getConnection(this.url, this.usr, this.pss);  
  206.                     this.connStatus[poolConnection.connNbr]="Y";  
  207.                     System.out.println(poolConnection.connNbr+"连接已重建");  
  208.                     result = true;//告知调用者连接已重建 
  209.                 }catch(SQLException e){  
  210.                     System.out.println(e.getMessage());  
  211.                 }catch(Exception e){  
  212.                     System.out.println(e.getMessage());//other exceptions 
  213.                 }     
  214.             }  
  215.         }  
  216.         return result;  
  217.     }  
  218.           
  219.     void freeConn(int i){  
  220.         try{  
  221.             if(i==-1){  
  222.                 System.out.println("i=-1,不需要释放");  
  223.             }else{  
  224.                 this.connections[i].commit();  
  225.             }  
  226.         }catch(SQLException e){  
  227.             System.out.println(e.getMessage());  
  228.         }catch(Exception e){  
  229.             System.out.println(e.getMessage());//other exceptions 
  230.         }  
  231.         this.connStatus[i]="Y";  
  232.     }  
  233. }

31/3123>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号