1. 程式人生 > >自定義JDBC資料庫連線池小例子

自定義JDBC資料庫連線池小例子

上篇文章中寫了一個JDBC的小例子,這篇文章寫個資料庫連線池的小例子吧。

package com.zkn.newlearn.jdbc.mysql.third;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.Properties;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Created by wb-zhangkenan on 2017/5/3.
 *
 * @date 2017/05/03
 */
public class DataSourcePoolNew {
    /**
     * 最大連線數
     */
    private static final int COUNT = 10;
    /**
     * 存放資料庫
     */
    private static final LinkedList<Connection> connections = new LinkedList<>();
    /**
     * 建立鎖
     */
    private static final ReentrantLock lock = new ReentrantLock();
    private static final Condition notEmpty = lock.newCondition();
    private static final Condition notFull = lock.newCondition();
    /**
     * 資料庫連線
     */
    private static String URL;
    /**
     * 使用者名稱
     */
    private static String USER_NAME;
    /**
     * 密碼
     */
    private static String PASS_WORD;
    /**
     * 驅動型別
     */
    private static String DRIVER_CLASS_NAME;
    /**
     * 存放屬性資訊
     */
    private static Properties properties = new Properties();

    /**
     * 初始化資訊
     */
    static {
        InputStream is = DataSourcePoolNew.class.getResourceAsStream("driver.properties");
        try {
            properties.load(is);
            URL = (String) properties.get("url");
            USER_NAME = (String) properties.get("userName");
            PASS_WORD = (String) properties.get("passWord");
            DRIVER_CLASS_NAME = (String) properties.get("driverClassName");
            //載入驅動
            Class.forName(DRIVER_CLASS_NAME);
            Connection connection = null;
            for (int i = 0; i < 10; i++) {
                connection = DriverManager.getConnection(URL, USER_NAME, PASS_WORD);
                connections.add(connection);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 獲取Connection
     */
    public static Connection getConnection() {
        final ReentrantLock reentrantLock = lock;
        reentrantLock.lock();
        try {
            //如果沒有連線了,則等待著新放入的連線
            if (connections.isEmpty()) {
                notEmpty.await();
            }
            Connection connection = connections.removeFirst();
            notFull.signalAll();
            return connection;
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            reentrantLock.unlock();
        }
        return null;
    }

    /**
     * 釋放連線
     *
     * @param connection
     */
    public static void release(Connection connection) {
        final ReentrantLock reentrantLock = lock;
        reentrantLock.lock();
        try {
            if (connections.size() == COUNT) {
                notFull.await();
            }
            if (connection == null || connection.isClosed()) {
                connections.add(DriverManager.getConnection(URL, USER_NAME, PASS_WORD));
                notEmpty.signalAll();
                return;
            }
            //恢復預設值
            if (connection.getAutoCommit() == false) {
                connection.setAutoCommit(true);
            }
            connections.add(connection);
            notEmpty.signalAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            reentrantLock.unlock();
        }
    }

}
CloseUtils:
package com.zkn.newlearn.jdbc.mysql.second;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Created by wb-zhangkenan on 2017/5/3.
 *
 * @date 2017/05/03
 */
public final class CloseUtils {

    private static Logger log = LoggerFactory.getLogger(CloseUtils.class);

    /**
     * 關閉ResultSet
     *
     * @param resultSet
     */
    public static void close(ResultSet resultSet) {
        if (resultSet != null) {
            try {
                log.info("關閉了");
                resultSet.close();
            } catch (SQLException e) {
                log.error("關閉resultSet出現異常!!!");
            }
        }
    }

    /**
     * 關閉statement
     *
     * @param statement
     */
    public static void close(Statement statement) {
        if (statement != null) {
            try {
                statement.close();
            } catch (SQLException e) {
                log.error("關閉statement出現異常!!!");
            }
        }
    }

    /**
     * 關閉preparedStatement
     *
     * @param preparedStatement
     */
    public static void close(PreparedStatement preparedStatement) {
        if (preparedStatement != null) {
            try {
                preparedStatement.close();
            } catch (SQLException e) {
                log.error("關閉preparedStatement出現異常!!!");
            }
        }
    }

    /**
     * 關閉connection
     * @param connection
     */
    public static void close(Connection connection) {
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
                log.error("關閉connection出現異常!!!");
            }
        }
    }
}
DEMO:
package com.zkn.newlearn.jdbc.mysql.third;

import com.zkn.newlearn.jdbc.mysql.second.CloseUtils;
import org.junit.Test;
import java.sql.*;

/**
 * Created by zkn on 2017/5/3.
 */
public class JDBCPoolTest {


    /**
     * 查詢操作
     */
    @Test
    public void testStatementQuery() {
        Connection connection = null;
        Statement statement = null;
        ResultSet resultSet = null;
        try {
            connection = DataSourcePoolNew.getConnection();
            if(connection == null){
                return;
            }
            //獲取sql的宣告
            statement = connection.createStatement();
            //執行查詢的操作
            resultSet = statement.executeQuery("SELECT * FROM province_china");
            //取出查詢出來的資料
            StringBuilder sb = new StringBuilder();
            while (resultSet.next()) {
                sb.append(resultSet.getLong("id")).append("  ");
                //這裡需要注意的是下標是從1開始的,不是從0開始的
                sb.append(resultSet.getString(2)).append("  ");
                sb.append(resultSet.getString("cname")).append("  ");
                System.out.println(sb.toString());
                //清空原來的資料
                sb.delete(0, sb.length());
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            CloseUtils.close(resultSet);
            CloseUtils.close(statement);
            DataSourcePoolNew.release(connection);
        }
    }

    /**
     * 預編譯查詢
     */
    @Test
    public void testPreparedStatement() {
        Connection connection = null;
        PreparedStatement pst = null;
        ResultSet resultSet = null;
        try {
            //獲取連線
            connection = DataSourcePoolNew.getConnection();
            if(connection == null){
                return;
            }
            String sql = "SELECT * FROM TABLE_NAME WHERE EMPID = ?";
            //獲取sql宣告
            pst = connection.prepareStatement(sql);
            //pst.setLong(1,2);
            //封裝查詢條件
            pst.setString(1, "32151");
            //執行sql的操作
            resultSet = pst.executeQuery();
            StringBuilder sb = new StringBuilder();
            while (resultSet.next()) {
                sb.append(resultSet.getLong("id")).append(" ");
                sb.append(resultSet.getString(2));
                System.out.println(sb.toString());
                //清空原來的資料
                sb.delete(0, sb.length());
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            closeResource(connection,pst,resultSet);
        }
    }

    /**
     * 單條插入
     */
    @Test
    public void testInsert() {
        Connection connection = null;
        PreparedStatement pst = null;
        ResultSet resultSet = null;
        try {
            //獲取連線
            connection = DataSourcePoolNew.getConnection();
            if(connection == null){
                return;
            }
            //自動提交為false
            connection.setAutoCommit(false);
            //建立sql宣告
            pst = connection.prepareStatement(
                    "INSERT INTO TABLE_NAME (NAME,EMPID,ORG_ID,ORG_CODE,IS_ADMIN,GMT_CREATE,GMT_MODIFIED) VALUES (?,"
                            + "?,?,?,?,now(),now())",
                    Statement.RETURN_GENERATED_KEYS);
            pst.setString(1, "張三");
            pst.setString(2, "784550");
            pst.setLong(3, 2);
            pst.setString(4, "0.1.2");
            pst.setInt(5, 1);
            //執行插入操作
            int count = pst.executeUpdate();
            if (count > 0) {
                System.out.println("插入成功!");
            } else {
                System.out.println("插入失敗!");
            }
            resultSet = pst.getGeneratedKeys();
            while (resultSet.next()) {
                System.out.println(String.format("主鍵值為%d", resultSet.getLong(1)));
            }
            //提交操作
            connection.commit();
        } catch (SQLException e) {
            e.printStackTrace();
            //異常回滾
            try {
                connection.rollback();
            } catch (SQLException ee) {
                ee.printStackTrace();
            }
        } finally {
            closeResource(connection,pst,resultSet);
        }
    }

    /**
     * 批量插入 需要設定 rewriteBatchedStatements=true
     */
    @Test
    public void testBatchInsert() {
        Connection connection = null;
        PreparedStatement pst = null;
        ResultSet resultSet = null;
        try {
            //獲取連線
            connection = DataSourcePoolNew.getConnection();
            if(connection == null){
                return;
            }
            //自動提交為false
            connection.setAutoCommit(false);
            //建立sql宣告
            pst = connection.prepareStatement(
                    "INSERT INTO TABLE_NAME (NAME,EMPID,ORG_ID,ORG_CODE,IS_ADMIN,GMT_CREATE,GMT_MODIFIED) VALUES (?,"
                            + "?,?,?,?,now(),now())",
                    Statement.RETURN_GENERATED_KEYS);
            for (int i = 0; i < 10; i++) {
                pst.setString(1, "張三");
                pst.setString(2, "784550");
                pst.setLong(3, 2);
                pst.setString(4, "0.1.2");
                pst.setInt(5, 1);
                pst.addBatch();
            }
            int[] count = pst.executeBatch();
            if (count != null && count.length > 0) {
                System.out.println("插入成功!");
            } else {
                System.out.println("插入失敗!");
            }
            resultSet = pst.getGeneratedKeys();
            while (resultSet.next()) {
                System.out.println(String.format("主鍵值為%d", resultSet.getLong(1)));
            }
            //提交操作
            connection.commit();
        } catch (SQLException e) {
            e.printStackTrace();
            //異常回滾
            try {
                connection.rollback();
            } catch (SQLException ee) {
                ee.printStackTrace();
            }
        } finally {
            closeResource(connection,pst,resultSet);
        }
    }

    /**
     * 測試更新操作
     */
    @Test
    public void testUpdate() {
        Connection connection = null;
        PreparedStatement pst = null;
        try {
            //獲取連線
            connection = DataSourcePoolNew.getConnection();
            if(connection == null){
                return;
            }
            //自動提交為false
            connection.setAutoCommit(false);
            //建立sql宣告
            pst = connection.prepareStatement("update TABLE_NAME set name = ? where id >=? and id <= ? ");
            pst.setString(1, "李思思");
            pst.setLong(2, 1972);
            pst.setLong(3, 1995);
            int count = pst.executeUpdate();
            if (count > 0) {
                System.out.println("更新成功!");
            } else {
                System.out.println("更新失敗");
                return;
            }
            //提交操作
            connection.commit();
        } catch (SQLException e) {
            e.printStackTrace();
            //異常回滾
            try {
                connection.rollback();
            } catch (SQLException ee) {
                ee.printStackTrace();
            }
        } finally {
            closeResource(connection,pst);
        }
    }

    /**
     * 測試刪除操作
     */
    @Test
    public void testDelete() {
        Connection connection = null;
        PreparedStatement pst = null;
        try {
            //獲取連線
            connection = DataSourcePoolNew.getConnection();
            if(connection == null){
                return;
            }
            //自動提交為false
            connection.setAutoCommit(false);
            //建立sql的宣告
            pst = connection.prepareStatement("DELETE FROM TABLE_NAME WHERE ID >=? AND ID <=? ");
            pst.setLong(1, 1972);
            pst.setLong(2, 1995);
            //執行sql
            pst.executeUpdate();
            //提交
            connection.commit();
        } catch (SQLException e) {
            e.printStackTrace();
            //異常回滾
            try {
                connection.rollback();
            } catch (SQLException ee) {
                ee.printStackTrace();
            }
        } finally {
            closeResource(connection,pst);
        }
    }

    private void closeResource(Connection connection, PreparedStatement statement, ResultSet resultSet) {
        CloseUtils.close(resultSet);
        closeResource(connection, statement);
    }

    private void closeResource(Connection connection, PreparedStatement statement) {
        CloseUtils.close(statement);
        DataSourcePoolNew.release(connection);
    }

}


相關推薦

定義JDBC資料庫連線例子

上篇文章中寫了一個JDBC的小例子,這篇文章寫個資料庫連線池的小例子吧。 package com.zkn.newlearn.jdbc.mysql.third; import java.io.IOException; import java.io.InputStream;

Javaweb總結2—定義JDBC資料庫連線

什麼是資料庫連線池呢? 資料庫連線池簡而言之就是一個容器裡存放一些資料庫連線。 那問題來了,要資料庫連線池有什麼用呢? 哈哈不用急,接下來我們一起慢慢分析分析 我們仔細觀察這個連線池,有沒有解決剛剛開始的疑問呢? 實現連線池先繼承一個DataSourse類,當然也可以選擇不繼承它來寫

定義實現資料庫連線

資料庫連線池: >資料庫的連線物件建立工作,比較消耗效能 >一開始先在記憶體中開闢一塊空間(集合) , 先往池子裡面放置 多個連線物件。  後面需要連線的話,直接從池子裡面去。不要去自己建立連線了。  使用完畢, 要記得歸還連線。確保連線物件能迴圈利用。即建立

JDBC資料庫連線連線資料庫資料庫操作DAO層設計通用更新及查詢方法(二)

上篇文章主要介紹了通過資料庫連線池連線資料庫,然後設計了對資料庫通用更新和查詢方法,本篇文章主要通過例項介紹上篇文章定義的對資料庫操作的幾個方法的使用:     首先我們先在資料庫建立一個學生資訊表Student欄位如圖: 建立好表將配置檔案的資訊改好然後需要建立一

JDBC資料庫連線連線資料庫資料庫操作DAO層設計通用更新及查詢方法(一)

該篇文章介紹了資料庫連線池獲取資料庫連線以及資料庫操作的基本使用,然後主要提供了java專案案例中dao層的一種設計,利用反射的原理定義了通用的查詢方法可以對應所有的表和例項。文章中的每段程式碼都提供了詳細的註釋及邏輯步驟 首先匯入資料庫連線的所需要的jar包:    

[課本10.1.4]JDBC資料庫連線- C3P0資料來源--通過構造方法建立資料來源物件--通過配置檔案建立資料來源物件[推薦]

JDBC- C3P0資料來源 1 /*重點提醒*/ 2 連線資料庫的較低的jar包版本會與較高版本的mysql版本有衝突; 3 通過把mysql 8.0的版本降到5.5, jar包仍使用較高的 mysql-connector-java-5.1.7-bin.jar, 完美解決衝突.  

Java個人總結——JDBC資料庫連線(二)

三種常見的資料庫連線池 一、DBCP連線池 DBCP(DataBase connection pool),[資料庫連線池]。是 apache 上的一個 java 連線池專案,也是 tomcat 使用的連線池元件。單獨使用dbcp需要2個包:commons-dbcp.

八、JDBC-資料庫連線

JDBC資料庫連線池的必要性 一、在使用開發基於資料庫的web程式時,傳統的模式基本是按一下步驟: 1)在主程式(如servlet/beans)中建立資料庫連線 2)進行sql操作 3)斷開資料庫連線 二、這種模式開發,存在的問題: 1)普通的JDBC資料庫連線使用Drive

JDBC-資料庫連線/操作

1.資料庫連線池的必要性 不使用資料庫連線池: 在使用開發基於資料庫的web程式時,傳統的模式基本是按以下步驟:   在主程式(如servlet、beans、DAO)中建立資料庫連線。 進行sql操作 斷開資料庫連線。 這種模式開發,存在的問題: 普通的JDBC

JDBC資料庫連線實現原理(手動實現)

一、普通的資料庫連線     如下圖所示,個使用者獲取資料庫資料都要單獨建立一個jdbc連線,當用戶獲取資料完成後再將連線釋放,可見對cpu的資源消耗很大。  二

JDBC資料庫連線配置

dbcp配置中文版本,翻譯自apache 官方文件,原文請見http://commons.apache.org/dbcp/configuration.html。 引數 描述 username 傳遞給JDBC驅動的用於建立連線的使用者名稱 password 傳遞給JDBC驅動的用於建立連線的密碼 url

JDBC 資料庫連線(DBCP、C3P0) 詳解

前言   這段時間狀態有一點浮躁,希望自己靜下心來。還有特別多的東西還沒有學懂。需要學習的東西非常的多,加油! 一、JDBC複習   Java Data Base Connectivity,java資料庫連線,在需要儲存一些資料,或者拿到一些資料的時候,就需要往

Java jdbc資料庫連線總結!

1. 引言   近年來,隨著Internet/Intranet建網技術的飛速發展和在世界範圍內的迅速普及,計算機   應用程式已從傳統的桌面應用轉到Web應用。基於B/S(Browser/Server)架構的3層開發模式逐漸取代C/S(Client/Server)架構的開發

Servlet的JDBC 資料庫連線

國慶的最後的時候,花了些時間整理下筆記等東東:(一些亂亂的東西) 純servlet的demo中使用的; JDBC 資料庫連線池:(程式碼測試不能用,不過思路應該是對的,後來改好的  程式碼不對 沒有

設定JDBC資料庫連線

前言     JDBC作為J2EE的規範之一,它定義了連線資料庫的介面,封裝了連線資料庫的細節問題,給開發人員極大的方便。開發人員只需要實現這些介面,就可以連線不同的資料庫,不需要針對不同資料庫寫不

JDBC資料庫連線c3po配置

使用前需要先匯入c3po開源jar包, import java.sql.Connection; import java.sql.SQLException; import com.mchange.v2.c3p0.ComboPooledDataSource; import co

Java自學-JDBC 資料庫連線

## 資料庫連線池 與[執行緒池](http://how2j.cn/k/thread/thread-threadpool/357.html?p=43278)類似的,資料庫也有一個數據庫連線池。 不過他們的實現思路是不一樣的。 本章節講解了自定義資料庫連線池類:ConnectionPool,雖然不是很完善和

定義資料庫連線實現方式 MySQL

應用程式直接獲取資料庫連線缺點 使用者每次請求都會建立一次資料庫連線,並且資料庫建立連線會消耗相對大的資源和時間。 如果針對於個別的工具或者是大量的程式碼測試甚至系統執行,對資料庫操作次數頻繁,極大的佔用資料庫資源,有可能會發生宕機或者記憶體溢位的現象。 而在大多的專案中,常常用到阿里巴

經典的java定義資料庫連線程式碼

import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.Driver; import java.sql.DriverManager; import j

定義資料庫連線實現方式 MySQL

應用程式直接獲取資料庫連線缺點 使用者每次請求都會建立一次資料庫連線,並且資料庫建立連線會消耗相對大的資源和時間。 如果針對於個別的工具或者是大量的程式碼測試甚至系統執行,對資料庫操作次數頻繁,極大的佔用資料庫資源,有可能會發生宕機或者記憶體溢位的現象。 而在大多的專案中