一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - 自定義一個簡單的JDBC連接池實現方法

自定義一個簡單的JDBC連接池實現方法

2021-03-08 12:05samluby Java教程

下面小編就為大家分享一篇自定義一個簡單的JDBC連接池實現方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧

一、什么是JDBC連接池

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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;
 }

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

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

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

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

對自定義連接池的分析:

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

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

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

編碼:

1.創建一個類MyDataSource 并實現DataSource接口

當此類加載時它就需要有一個容器來存放Connection,所以定義一個靜態的屬性:

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

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public Connection getOneConnection(){
  Connection conn = null;
  try{
   //此處通過外部的properties文件來獲取的數據,這樣更加靈活。
   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文件的獲取的數據,可根據實際情況來選擇

3.初始化幾個連接放入容器中。可以使用靜態代碼塊來實現,但是如果沒有使用此數據源那么就造成了資源的浪費,所以我考慮將初始化幾個連接的實現放到他的構造方法中,即當需要此連接池的時候他才會隨之創建幾個連接。如下:

?
1
2
3
4
5
6
public MyDataSource() {
  for (int i = 0; i < 5; i++) {
   Connection conn = getOneConnection();//調用創建連接的方法
   connectionList.add(conn);
  }
 }

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

?
1
2
3
4
5
6
7
8
9
10
@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.創建一個對象返回的方法,即將用完的連接放入歸還到連接池中

 

?
1
2
3
public void backConnection(Connection conn){
  connectionList.add(conn);
 }

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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);
  }
 }

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

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

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

優化:

1.新建一個類MyConnection來實現Connection接口,其中他有屬性類型為Connection conn和一個Liis<Connection>。

?
1
2
3
4
5
6
7
private Connection conn;
 private List<Connection> pool;
 
 public MyConnection(Connection conn, List<Connection> pool) {
  this.conn = conn;
  this.pool = pool;
 }

2.然后實現接口的close方法

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

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

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

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

?
1
2
3
4
5
6
7
public MyDataSource2() {
  for (int i = 0; i < 5; i++) {
   Connection conn = getOneConnection();
   MyConnection myConn = new MyConnection(conn, connectionList);
   connectionList.add(myConn);
  }
 }
?
1
2
3
4
5
6
7
8
9
10
11
@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;
 }

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

以上這篇自定義一個簡單的JDBC連接池實現方法就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持服務器之家。

原文鏈接:http://www.cnblogs.com/samluby/archive/2017/12/19/8068277.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 亚洲AV无码专区国产精品麻豆 | 欧美不卡一区二区三区 | 九九国产在线视频 | aⅴ视频在线免播放观看 | 爱福利视频一区 | 好男人天堂网 | 日韩伦理在线看 | 微拍秒拍99福利精品小视频 | 欧美又硬又粗又长又大 | 天天白天天谢天天啦 | 亚洲精品在线免费看 | 精品国产一级在线观看 | 风间由美m3u8在线 | 8x8x极品国产在线 | 催眠白丝舞蹈老师小说 | 动漫美女人物被黄漫在线看 | 九色PORNY真实丨国产大胸 | 亚洲玖玖 | 天堂樱桃bt在线www | 亚洲精品6久久久久中文字幕 | 久久综合久久伊人 | 亚洲成人国产 | 精品成人网 | 日本高清中文字幕一区二区三区 | 日本剧情片在线播放中文版 | 日本男男gayxxxxx免费 | 欧美精品一区二区三区免费观看 | jiujiure精品 | 男人天堂中文字幕 | 天天翘| 久久中文字幕免费高清 | 国产男人搡女人免费视频 | 亚洲欧美日韩成人一区在线 | 久久这里只有精品视频e | 好爽好深好猛好舒服视频上 | babes性欧美30| 国产成人yy精品1024在线 | 四川女人偷人真实视频 | 国产一级视频在线观看 | 狠狠色狠狠色综合日日小蛇 | 国产精品露脸国语对白99 |