最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

自定義一個(gè)簡(jiǎn)單的JDBC連接池實(shí)現(xiàn)方法

 更新時(shí)間:2017年12月20日 08:45:31   作者:samluby  
下面小編就為大家分享一篇自定義一個(gè)簡(jiǎn)單的JDBC連接池實(shí)現(xiàn)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧

一、什么是JDBC連接池?

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

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)然,我們可以將其封裝成一個(gè)工具類(lèi)來(lái)訪問(wèn)(上圖以封裝好Connection的連接),但是每一次連接都需要取加載一次是不是很浪費(fèi)性能,為了優(yōu)化性能,那么就出現(xiàn)了連接池。

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

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

二、自定義一個(gè)簡(jiǎn)單的連接池

對(duì)自定義連接池的分析:

1.2.因?yàn)槭沁B接池 ,我們需要實(shí)現(xiàn)DataSource接口,并實(shí)現(xiàn)其中的方法,基于我們的情況,我們關(guān)于與getConnection()方法;

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

3.連接的銷(xiāo)毀并不是銷(xiāo)毀連接,而是將連接歸還給連接池

編碼:

1.創(chuàng)建一個(gè)類(lèi)MyDataSource 并實(shí)現(xiàn)DataSource接口

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

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

2.因?yàn)樾枰~@得數(shù)據(jù)庫(kù)連接,所以我們封裝一個(gè)獲取數(shù)據(jù)庫(kù)連接的方法

public Connection getOneConnection(){
  Connection conn = null;
  try{
   //此處通過(guò)外部的properties文件來(lái)獲取的數(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;
 }

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

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

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

4.現(xiàn)在開(kāi)始重寫(xiě)外部從此連接池中獲取連接的方法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)建一個(gè)對(duì)象返回的方法,即將用完的連接放入歸還到連接池中


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

OK,這樣就完成了一個(gè)簡(jiǎn)單的自定義連接池,測(cè)試代碼如下:

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);
  }
 }

因?yàn)楹雎裕业拇a中沒(méi)有關(guān)閉其他兩個(gè)對(duì)象。

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

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

優(yōu)化:

1.新建一個(gè)類(lèi)MyConnection來(lái)實(shí)現(xiàn)Connection接口,其中他有屬性類(lèi)型為Connection conn和一個(gè)Liis<Connection>。

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

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

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

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

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

4.然后刪除掉MyDataSource類(lèi)中歸還連接的方法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方法就不會(huì)去銷(xiāo)毀連接了,會(huì)正確的歸還給了連接池了,對(duì)測(cè)試代碼稍做修改即可測(cè)試。

以上這篇自定義一個(gè)簡(jiǎn)單的JDBC連接池實(shí)現(xiàn)方法就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 解決Springboot啟動(dòng)報(bào)錯(cuò):類(lèi)文件具有錯(cuò)誤的版本61.0,應(yīng)為?52.0

    解決Springboot啟動(dòng)報(bào)錯(cuò):類(lèi)文件具有錯(cuò)誤的版本61.0,應(yīng)為?52.0

    這篇文章主要給大家介紹了關(guān)于解決Springboot啟動(dòng)報(bào)錯(cuò):類(lèi)文件具有錯(cuò)誤的版本?61.0,應(yīng)為?52.0的相關(guān)資料,這是查閱了網(wǎng)上的很多資料才解決的,分享給大家,需要的朋友可以參考下
    2023-01-01
  • Java中Scanner的常用方法總結(jié)(一次學(xué)懂)

    Java中Scanner的常用方法總結(jié)(一次學(xué)懂)

    這篇文章主要給大家介紹了關(guān)于Java中Scanner常用方法的相關(guān)資料,Java中的Scanner是一個(gè)用于讀取用戶輸入的類(lèi),它可以讀取各種類(lèi)型的數(shù)據(jù),包括整數(shù)、浮點(diǎn)數(shù)、字符串等等,需要的朋友可以參考下
    2023-11-11
  • 深度理解SpringMVC中的HandlerMapping

    深度理解SpringMVC中的HandlerMapping

    這篇文章主要介紹了深度理解SpringMVC中的HandlerMapping,HandlerMapping的作用根據(jù)request找到對(duì)應(yīng)的處理器Handler,在HandlerMapping接口中有一個(gè)唯一的方法getHanler,需要的朋友可以參考下
    2023-09-09
  • 詳解SpringMVC在IDEA中的第一個(gè)程序

    詳解SpringMVC在IDEA中的第一個(gè)程序

    Spring MVC 屬于Spring Framework的一部分,是一種Spring框架內(nèi)置的MVC的實(shí)現(xiàn)。這篇文章主要介紹了SpringMVC在IDEA中的第一個(gè)程序,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-09-09
  • SpringBoot的攔截器中依賴注入為null的解決方法

    SpringBoot的攔截器中依賴注入為null的解決方法

    這篇文章主要介紹了SpringBoot的攔截器中依賴注入為null的解決方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-06-06
  • java 保留兩位小數(shù)的幾種方法

    java 保留兩位小數(shù)的幾種方法

    這篇文章主要介紹了JAVA中小數(shù)點(diǎn)后保留兩位的幾種方法,并有小實(shí)例,希望能幫助有所需要的同學(xué)
    2016-07-07
  • Spring Boot下的Job定時(shí)任務(wù)

    Spring Boot下的Job定時(shí)任務(wù)

    編寫(xiě)Job定時(shí)執(zhí)行任務(wù)十分有用,能解決很多問(wèn)題,這次實(shí)習(xí)的項(xiàng)目里做了一下系統(tǒng)定時(shí)更新三方系統(tǒng)訂單狀態(tài)的功能,這里用到了Spring的定時(shí)任務(wù)使用的非常方便,下面總結(jié)一下如何使用,感興趣的朋友參考下吧
    2017-05-05
  • Java的jps命令簡(jiǎn)介及使用示例詳解

    Java的jps命令簡(jiǎn)介及使用示例詳解

    jps是jdk提供的一個(gè)查看當(dāng)前java進(jìn)程的小工具,?可以看做是JavaVirtual?Machine?Process?Status?Tool的縮寫(xiě),非常簡(jiǎn)單實(shí)用,本文重點(diǎn)給大家介紹下Java的jps命令使用,感興趣的朋友一起看看吧
    2022-03-03
  • Java如何基于DOM解析xml文件

    Java如何基于DOM解析xml文件

    這篇文章主要介紹了Java如何基于DOM解析xml文件,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-09-09
  • JDK1.6集合框架bug 6260652解析

    JDK1.6集合框架bug 6260652解析

    這篇文章主要為大家解析了JDK1.6集合框架bug:c.toArray might (incorrectly) not return Object[] (see 6260652),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-10-10

最新評(píng)論

无锡市| 孝昌县| 临江市| 永州市| 永寿县| 绵竹市| 本溪| 缙云县| 泗阳县| 崇礼县| 彭山县| 奇台县| 尤溪县| 上饶市| 攀枝花市| 鹤庆县| 邵东县| 永清县| 麟游县| 海安县| 涿州市| 池州市| 时尚| 天柱县| 垦利县| 外汇| 曲周县| 桂平市| 桐乡市| 庆城县| 积石山| 太白县| 焦作市| 阳江市| 陆川县| 平定县| 汾阳市| 股票| 西平县| 邵东县| 观塘区|