真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

自定義一個簡單的JDBC連接池實現(xiàn)方法

一、什么是JDBC連接池?

10年積累的成都做網(wǎng)站、成都網(wǎng)站建設(shè)經(jīng)驗,可以快速應(yīng)對客戶對網(wǎng)站的新想法和需求。提供各種問題對應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識你,你也不認(rèn)識我。但先網(wǎng)站制作后付款的網(wǎng)站建設(shè)流程,更有修武免費網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。

在傳統(tǒng)的JDBC連接中,每次獲得一個Connection連接都需要加載通過一些繁雜的代碼去獲取,例如以下代碼:

public static Connection getConn(){
  Connection conn = null;
  String url = "jdbc:MySQL://localhost:3306/test";
  String user = "root";
  String password = "root";
  try {
   Class.forName("com.mysql.jdbc.Driver");
   conn = DriverManager.getConnection(url, user, password);
  } catch (ClassNotFoundException e) {
   e.printStackTrace();
  } catch (SQLException e) {
   e.printStackTrace();
  }
  return conn;
 }

這樣繁雜的操作只為了獲取一次連接,當(dāng)然,我們可以將其封裝成一個工具類來訪問(上圖以封裝好Connection的連接),但是每一次連接都需要取加載一次是不是很浪費性能,為了優(yōu)化性能,那么就出現(xiàn)了連接池。

連接池在初始化的時候就創(chuàng)建了幾個連接供我們使用,當(dāng)我們需要連接時只需要從連接池中獲取已存在的連接,當(dāng)初始化的幾個連接都沒有時,會重新創(chuàng)建一個連接,使用完連接后不會去銷毀連接,而是歸還給連接池供后面需要連接的使用。(當(dāng)然,連接池不僅僅只是這么簡單,這里就只做這些介紹)

常用的連接池有DBCP、C3P0,現(xiàn)在最主流是好像是阿里的Druid連接池,還有tomcat的自帶的JNDI連接池

二、自定義一個簡單的連接池

對自定義連接池的分析:

1.2.因為是連接池 ,我們需要實現(xiàn)DataSource接口,并實現(xiàn)其中的方法,基于我們的情況,我們關(guān)于與getConnection()方法;

2.既然要存放幾個連接對象,那么我們用一個集合來存放它,基于會經(jīng)常操作增加和刪除那么選用LinkedList;

3.連接的銷毀并不是銷毀連接,而是將連接歸還給連接池

編碼:

1.創(chuàng)建一個類MyDataSource 并實現(xiàn)DataSource接口

當(dāng)此類加載時它就需要有一個容器來存放Connection,所以定義一個靜態(tài)的屬性:

private static List connectionList = new LinkedList<>();

2.因為需要取獲得數(shù)據(jù)庫連接,所以我們封裝一個獲取數(shù)據(jù)庫連接的方法

public Connection getOneConnection(){
  Connection conn = null;
  try{
   //此處通過外部的properties文件來獲取的數(shù)據(jù),這樣更加靈活。
   InputStream in = MyDataSource.class.getClassLoader().
     getResourceAsStream("jdbc/jdbc.properties");
   Properties pro = new Properties();
   pro.load(in);
   driver = pro.getProperty("driver");
   url = pro.getProperty("url");
   username = pro.getProperty("user");
   password = pro.getProperty("password");
   Class.forName(driver);
   conn = DriverManager.getConnection(url,username,password);
  }catch (Exception e){
   e.getStackTrace();
  }
  return conn;
 }

注意的是我這里通過propertie文件的獲取的數(shù)據(jù),可根據(jù)實際情況來選擇

3.初始化幾個連接放入容器中??梢允褂渺o態(tài)代碼塊來實現(xiàn),但是如果沒有使用此數(shù)據(jù)源那么就造成了資源的浪費,所以我考慮將初始化幾個連接的實現(xiàn)放到他的構(gòu)造方法中,即當(dāng)需要此連接池的時候他才會隨之創(chuàng)建幾個連接。如下:

public MyDataSource() {
  for (int i = 0; i < 5; i++) {
   Connection conn = getOneConnection();//調(diào)用創(chuàng)建連接的方法
   connectionList.add(conn);
  }
 }

4.現(xiàn)在開始重寫外部從此連接池中獲取連接的方法getConnection()

@Override
 public Connection getConnection() throws SQLException {
  Connection conn = null;
  if(connectionList == null || connectionList.size() <= 0){
   Connection connection = getConnection();
   connectionList.add(connection);
  }
  conn = connectionList.remove(0);
  return conn;
 }

5.創(chuàng)建一個對象返回的方法,即將用完的連接放入歸還到連接池中

public void backConnection(Connection conn){
  connectionList.add(conn);
 }

OK,這樣就完成了一個簡單的自定義連接池,測試代碼如下:

public static void main( String[] args ) throws SQLException
 {
  MyDataSource dataSource = new MyDataSource();
  Connection conn = dataSource.getConnection();
  String sql = "select * from user where u_id = ?";
  PreparedStatement ps = null;
  ResultSet rs = null;
  try {
   ps = conn.prepareStatement(sql);
   ps.setInt(1, 1);
   rs = ps.executeQuery();
   while (rs.next()) {
    System.out.println("id="+rs.getInt(1));
    System.out.println("username="+rs.getString(2));
    System.out.println("password="+rs.getString(3));
   }
  } catch (SQLException e) {
   e.printStackTrace();
  } finally {
   dataSource.backConnection(conn);
  }
 }

因為忽略,我的代碼中沒有關(guān)閉其他兩個對象。

現(xiàn)在有一個小問題就是,我們的關(guān)閉連接是通過連接池的方法來實現(xiàn)的,但是,如果用戶調(diào)用Connection對象的close方法,那么連接時被銷毀了,并沒有返回給連接池,那么我們來優(yōu)化它,讓用戶使用close()方法不會去銷毀連接,而是去歸還連接。

方案有很多中,這里采用裝飾著模式的一種。

優(yōu)化:

1.新建一個類MyConnection來實現(xiàn)Connection接口,其中他有屬性類型為Connection conn和一個Liis

private Connection conn;
 private List pool;
 
 public MyConnection(Connection conn, List pool) {
  this.conn = conn;
  this.pool = pool;
 }

2.然后實現(xiàn)接口的close方法

 @Override
 public void close() throws SQLException {
  System.out.println("回收連接");
  pool.add(conn);
 }

3.然后實現(xiàn)他獲取Statement的方法,如果不實現(xiàn)那么獲取此Statement會出現(xiàn)空指針錯誤,我這里就只實現(xiàn)了PreparedStatement的獲取方法

@Override
 public PreparedStatement prepareStatement(String sql) throws SQLException {
  System.out.println("獲得Statement");
  return conn.prepareStatement(sql);
 }

4.然后刪除掉MyDataSource類中歸還連接的方法backConnection,并將構(gòu)造方法和獲取連接的方法做如下改造

public MyDataSource2() {
  for (int i = 0; i < 5; i++) {
   Connection conn = getOneConnection();
   MyConnection myConn = new MyConnection(conn, connectionList);
   connectionList.add(myConn);
  }
 }
@Override
 public Connection getConnection() throws SQLException {
  Connection conn = null;
  if(connectionList == null || connectionList.size() <= 0){
   Connection connection = getConnection();
   MyConnection myConn = new MyConnection(connection, connectionList);
   connectionList.add(myConn);
  }
  conn = connectionList.remove(0);
  return conn;
 }

好了,這樣用戶直接調(diào)用我們的Connection的close方法就不會去銷毀連接了,會正確的歸還給了連接池了,對測試代碼稍做修改即可測試。

以上這篇自定義一個簡單的JDBC連接池實現(xiàn)方法就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持創(chuàng)新互聯(lián)。


分享題目:自定義一個簡單的JDBC連接池實現(xiàn)方法
本文URL:http://weahome.cn/article/ipeopi.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部