1. 程式人生 > >Servlet的JDBC 資料庫連線池

Servlet的JDBC 資料庫連線池

國慶的最後的時候,花了些時間整理下筆記等東東:(一些亂亂的東西) 純servlet的demo中使用的; JDBC 資料庫連線池:(程式碼測試不能用,不過思路應該是對的,後來改好的  程式碼不對 沒有返回    下面的程式碼是可用的) 首先,需要一個繼承DataSource介面的類,這個就是地址池了; 改寫裡面的Connection getConnection()方法(無參的),這個是用來分配地址的,程式碼可以這麼寫,大概這樣: publicConnection getConnection()throwsSQLException{//給執行緒方法連線synchronized(pool){if(
pool.size()>0){//容器裡有東東
return pool.remove();//給一個出去}elseif(pool.size()==0&&count<maxPoolSize){ pool.add(createConnection());return pool.remove();}else{//容器沒有連線了,並且連線數已經超過最大值,讓執行緒等。try{ pool.wait();//讓執行緒等待}catch(InterruptedException e){// TODO: handle exception e.printStackTrace();}return
pool.remove();
}}//return null;} 這裡的pool就是一個容器,裡面就是連線池咯! 然後,在這個類裡要有建立連線資料庫的方法:Connection createConnection(); 不過這裡面的地址(放到地址池裡的是代理過的連線): //專門建立連線privateConnection createConnection(){Connection conn =null;try{Class.forName(driverClassName); conn=DriverManager.getConnection(url, user, password);//上面是正常的連線!!
//下面是對連線進行代理,為了就是在呼叫close方法時 不呼叫真正的close方法//而是我們自己寫 的 連線 回收的 方法 程式碼CloseMethodHandler handler =newCloseMethodHandler(pool);Connection proxyconnConnection = handler.createProxy(conn); count=count+1;//return conn;return proxyconnConnection;}catch(Exception e){ e.printStackTrace();}returnnull;} 當然 ,這裡對這個地址池 類的構造方法 還是要寫一下  ,要在構造的時候 先獲得基本的資料 並建立 幾個連線到地址池 privateLinkedList<Connection> pool=newLinkedList<Connection>();privateString driverClassName;privateString url;privateString user;privateString password;privateint count=0;//連線計數publicMyDataSource(int maxPoolSize,int initPoolSize,String driverClassName,String url,String user,String password){this.initPoolSize=initPoolSize;this.maxPoolSize=maxPoolSize;this.driverClassName=driverClassName;this.url=url;this.user=user;this.password=password;//建立三個連線for(int i =0; i < initPoolSize; i++){Connection conn =createConnection(); pool.add(conn);}} 這構造方法就沒什麼好說明的 了: 接下來:​要建立上面的CloseMethodHandler這個類了,這個類是用來建立 代理的; 也就是,代理原本正真的資料庫連線,以便在其呼叫close方法時,呼叫回收 和 執行緒 喚醒; 這個類必須繼承InvocationHandler這個介面,並重寫invoke(Object proxy, Method method, Object[] args)方法; 這個方法就是用來處理(攔截)代理物件方法使用的; publicclassCloseMethodHandlerimplementsInvocationHandler{privateConnection target;privateLinkedList<Connection> pool; //構造方法 是因為需要pool物件而建立的publicCloseMethodHandler(LinkedList<Connection> pool){this.pool=pool;}//target是被代理物件,建立一個代理物件//用來建立一個代理的物件 ,並將引數的真的物件 儲存起來先   /*不過我感覺這裡有問題,對引數的處理不太對的趕腳*/publicConnection createProxy(Connection target){System.out.println(target.getClass().getName());this.target=target; //這個就是一個建立 代理 的方法 引數 我也弄的不明白 好像是 源物件的例項化的方式 ,代理物件的型別(介面),實現代理的類(就是自己)/*感覺這個也有問題 對引數就是搞不明白*/return(Connection)Proxy.newProxyInstance(target.getClass().getClassLoader(),newClass[]{Connection.class},this);}//攔截被代理物件的方法的方法==》攔截Connection物件中close的方法。publicObject invoke(Object proxy,Method method,Object[] args)throwsThrowable{if(method.getName().equals("close")){//攔截synchronized(pool){ pool.add((Connection) proxy); pool.notify();//喚醒等待的執行緒}}else{ return method.invoke(target, args);//不攔截 //如果這個不返回 則所有的方法 都返回空}//問題就是在這裡了,這個原先沒有返回 所以所有的方法都被攔截了returnnull; //這裡是不能返回空 close方法是返回空 而其他的方法 是有 返回的}} 至於,這個地址池的使用,就很方便了,只要建立一個這個地址池的單例,調動裡面的方法來獲得資料庫的連線就可以了;; 資料庫連線池:(小結) 管理多個數據庫連線的容器-連線池。 特點: 裡面有多個連線。 這些連線一般不關閉。 負責分發和回收。 把Connection 的 close 改造成釋放連線,並且喚醒等待的執行緒。 使用代理:完成方法的改造 替代Connection的 close方法。 第三方成熟的資料庫連線池:C3P0,DBCP。 自定義資料庫連線: 1、實現javax.sql.DataSource介面。 2、重寫裡面一個getConnection()方法 3、設定一個連線數的最大值。(保護資料庫) 4、設定一個初始化的連線數。 5、負責回收。(連線不關閉,而是回到資料庫連線池,並變為空閒狀態。)。 6、設定執行緒等待和解鎖的機制。 當然這裡使用第三方的開源外掛是最好的,有:c3p0- 和 commons-pool -dbcp  這兩個常用的;這裡就試了下c3p0 是可以用的,另外一個似乎有版本問題!!!!我寫的demo有問題應該,,,