淺析B/S架構數據庫連接方式


前言
在許許多多的B/S架構系統中都涉及到了數據庫的鏈接,那么對於數據庫連接的方式有哪些?可能出現的問題是什么?
 
目錄
1.普通連接方式
2.單例模式
3.連接池
 
分析
普通連接:
下面是我們一般使用的普通連接方式的代碼(jsp)
package com.jdbc.dao;
import java.sql.*;
 
public class BaseDAO {
        //打開數據庫鏈接
        public Connection getConn()
        {
                Connection conn = null;
                try {
                        //加載驅動
                        Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
                        //打開鏈接
                        conn = DriverManager.getConnection("jdbc:sqlserver://localhost:1433;DatabaseName = epetDB","sa","sa");
                } catch (ClassNotFoundException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                } catch (SQLException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                }
                return conn;
        }
        //(重寫)關閉鏈接
        public void Close(Connection conn,PreparedStatement pstmt,ResultSet rs)
        {
                try {
                        //關閉結果集
                        if (rs != null) {
                                rs.close();
                        }
                        //關閉PerparedStatement對象
                        if (pstmt != null) {
                                pstmt.close();
                        }
                        //關閉鏈接
                        if (conn != null) {
                                conn.close();
                        }
                } catch (Exception e) {
                        // TODO: handle exception
                }
        }
        //(重寫)關閉鏈接
        public void Close(Connection conn,PreparedStatement pstmt)
        {
                try {
                        //關閉PerparedStatement對象
                        if (pstmt != null) {
                                pstmt.close();
                        }
                        //關閉鏈接
                        if (conn != null) {
                                conn.close();
                        }
                } catch (Exception e) {
                        // TODO: handle exception
                }
        }
        //增刪改操作
        public int Update(String sql,Object[] parm)
        {
                int iRet = 0;
                Connection conn = null;
                PreparedStatement pstmt = null;
                try {
                        conn = getConn();
                        pstmt = conn.prepareStatement(sql);
                        //循環賦值參數
                        for (int i = 0; i < parm.length; i++) {
                                //為預編譯sql設置參數
                                pstmt.setObject(i+1, parm);
                        }
                        //執行SQL語句
                        iRet = pstmt.executeUpdate();
                } catch (Exception e) {
                        e.printStackTrace();
                }
                finally
                {
                        Close(conn,pstmt);
                }
                return iRet;
        }
}

 

普及:

 

try{
//可能出現異常的代碼
}catch(Execption e){
//如果發生異常處理的代碼
}finally{
//無論是否異常都會執行的代碼
try catch finally java中異常處理機制

 

 

我們來分析一下寫一段代碼,其中Update方法是用來更新數據的,其中我們可以看到try中包含了getConn()方法用來獲取Connection連接對象,到最后我們可以在finally代碼塊中看到Close()方法用來關閉創建的Connection對象以及PreparedStatement對象,這么消耗我們很大的內存空間。

 

 

如果用戶同時點注冊按鈕那么服務器首先執行打開數據庫連接Connection多個用戶注冊就會打開多個Connection那么並且同時添加到數據庫,服務器就會在執行添加的時候就會發生異常。分不清楚用戶注冊的信息。

舉個例子:

 

左邊的三個人同時對另一人喊不同的一個字,右邊的一個人就會分不清,左邊三個人喊了什么?(可以做真人實例)
 
總結:
從分析中,我們看到普通的連接方式中無法處理並發問題!如果你想知道解決方法那么請繼續看下去。
 
單例連接:
下面一段單利模式中的數據庫連接代碼
package dao;
 
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
 
public class BaseDao {
        private String className = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
        private String url = "jdbc:sqlserver://localhost:1433;databasename=SQLTMP";
        private String user = "sa";
        private String pwd = "sa";
        private static Connection conn = null;
         
        private BaseDao(){
                try {
                        Class.forName(className);
                        conn = DriverManager.getConnection(url,user,pwd);
                } catch (ClassNotFoundException e) {
                        e.printStackTrace();
                } catch (SQLException e) {
                        e.printStackTrace();
                }
                 
        }
         
        public static Connection getConn(){
                if(conn != null){
                        return conn;
                }else{
                        new BaseDao();
                        return conn;
                }
        }
}
 
普及:
構造方法:訪問修飾符(public|private) 類名
構造方法在實例化的時候就會調用
 
我們分析一下這一段代碼中Connection在構造方法中創建用過getConn方法獲取連接。
 
 
我們從圖片中和代碼中可以看到全程中只有一個Connection連接,那么這樣就可以降低服務器的壓力,解決並發問題
 
總結:
 
從分析中,我們看到單例模式,可以減輕服務器的壓力,解決並發問題,如果夠仔細的話大家會發現 getConn 方法是一個靜態方法,而且其他屬性和方法都是 private 從而大大提高了安全性。這種連接方式適合: 個人開發和國家單位開發(安全性高)
 
連接池:
下面一段連接池數據庫連接代碼
context.xml
        <Resource  
                name="news"
                auth="Container"
                type="javax.sql.DataSource"
                maxActive="100"
                maxIdle="30"
                maxWait="1000"
                username="sa"
                password="sa"
                driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
                url="jdbc:sqlserver://localhost:1433;DatabaseName=NewsManagerSystem"
                /> 
Web.xml
<resource-ref>
    <description>news DataSource</description>
    <res-ref-name>news</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
  </resource-ref>   
 
package com.news.dao;
import java.sql.*;
 
import javax.naming.*;
import javax.sql.DataSource;
 
public class BaseDao {
        /**
         * 創建連接池
         * */
        public Connection getConn(){
                Connection conn = null;
                try {
                        Context ctx = new InitialContext();
                        DataSource ds = (DataSource)ctx.lookup("java:comp/env/news");
                        conn = ds.getConnection();
                } catch (NamingException e) {
                        e.printStackTrace();
                } catch (SQLException e) {
                        e.printStackTrace();
                }
                return conn;
        }
}

 

普及:

 

連接池:連接池是創建和管理一個連接的緩沖池的技術,這些連接准備好被任何需要他們的線程使用。
 
我們可以直接使用 getConn 方法獲得 Connection 並且執行數據操作,執行完成之后連接池會回收 Connection 這樣就解決了普通模式中的並發問題.
 
總結:
從分析中,我們看到 Connection 不需要創建,這樣就簡化編程模式,這樣 減少了連接的創建時間 ,連接池能夠使性能最大化,同事還能將資源利用控制在一定的水平之下,如果超過該水平,應用程序將崩潰而不僅僅是變慢。
 
寫在最后
清楚的了解B/S架構中的數據庫連接方式,在合適的情況下使用合適的連接方式感覺還是棒棒噠 ~ ~!
 

文章首鏈:http://bbs.ichunqiu.com/thread-8784-1-1.html


感謝您的閱讀,如果您學到了,請點贊(碼字不易)!


歡迎熱心園友補充!

作者:0nise

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM