1. 程式人生 > >基於Druid連線池的JDBC基礎框架

基於Druid連線池的JDBC基礎框架

JDBC連線池

        對於大多數應用程式,當它們正在處理通常需要數毫秒完成的事務時,僅需要能夠訪問JDBC連線的 1 個執行緒。當不處理事務時,這個連線就會閒置。相反,連線池允許閒置的連線被其它需要的執行緒使用。

        事實上,當一個執行緒需要用 JDBC 對一個 GBase 或其它資料庫操作時,它從池中請求一個連線。當這個執行緒使用完了這個連線,將它返回到連線池中,這樣這就可以被其它想使用它的執行緒使用。

        當連線從池中“借出”,它被請求它的執行緒專有地使用。從程式設計的角度來看,這和使用者的執行緒每當需要一個 JDBC 連線的時候呼叫DriverManager.getConnection() 是一樣的,採用連線池技術,可通過使用新的或已有的連線結束執行緒。

        連線池可以極大的改善使用者的 Java 應用程式的效能,同時減少全部資源的使用。連線池主要的優點有:

減少連線建立時間:

       雖然與其它資料庫相比 GBase 提供了較為快速連線功能,但是建立新的 JDBC 連線仍會招致網路和 JDBC 驅動的開銷。如果這類連線是“迴圈”使用的,使用該方式這些花銷就可避免。

簡化的程式設計模式:

        當使用連線池時,每一個單獨的執行緒能夠像建立了一個自己的 JDBC 連線一樣操作,允許使用者直接使用JDBC程式設計技術。

受控的資源使用:

        如果使用者不使用連線池,而是每當執行緒需要時建立一個新的連線,那麼使用者的應用程式的資源使用會產生非常大的浪費並且可能會導致高負載下的異常發生。

利用多型,反射,泛型能技術實現對資料庫的增刪改查等工作:

package com.softeem.jdbc.utils;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Properties;
import java.util.Set;

import com.alibaba.druid.pool.DruidDataSource;

/**
 * 通用資料庫工具類,基於Druid連線池實現
 * 包含以下功能
 * 1.獲取連線
 * 2.關閉資源
 * 3.執行通用的更新操作
 * 4.執行通用的查詢列表操作
 * 5.執行通用的查詢單條記錄操作
 * @author Luo
 *
 */

public class DBUtils {
	
	
	//宣告druid連線池物件
	private static DruidDataSource pool;
	
	/**資料庫 連結URL地址**/
	private static String url;
	/**賬號**/
	private static String username;
	/**密碼**/
	private static String password;
	/**初始連線數**/
	private static int initialSize;
	/**最大活動連線數**/
	private static int maxActive;
	/**最小閒置連線數**/
	private static int minIdle;
	/**連線耗盡時最大等待獲取連線時間**/
	private static long maxWait;
	
	private static String fileName = "/jdbc.properties";

	static {
		init();
	}
	
	/**
	 * 載入屬性檔案並讀取屬性檔案中的內容將其設定給連線資訊
	 * @param propName
	 */
	private static void loadProp(String propName) {
		fileName = propName;
		try {
			//屬性檔案位於src根目錄時,加"/"則不要使用ClassLoader,如果使用ClassLoader則無需"/"
			InputStream is = DBUtils.class.getResourceAsStream(fileName);
			Properties p = new Properties();
			p.load(is);
			
			
			url = p.getProperty("jdbc.url");
			username = p.getProperty("jdbc.username");
			password = p.getProperty("jdbc.password");
			
			initialSize = Integer.parseInt(p.getProperty("initialSize"));
			maxActive = Integer.parseInt(p.getProperty("maxActive"));
			maxWait = Integer.parseInt(p.getProperty("maxWait"));
			minIdle = Integer.parseInt(p.getProperty("minIdle"));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	private static void init() {
		pool = new DruidDataSource();
		//載入屬性檔案,初始化配置
		loadProp(fileName);
		pool.setUrl(url);
		pool.setUsername(username);
		pool.setPassword(password);
		
		//設定連線池中初始連線數
		pool.setInitialSize(initialSize);
		//設定最大連線數
		pool.setMaxActive(maxActive);
		//設定最小的閒置連結數
		pool.setMinIdle(minIdle);
		//設定最大的等待時間(等待獲取連結的時間)
		pool.setMaxWait(maxWait);
	}
	
	/**
	 * 連結獲取
	 * @return
	 */
	public static Connection getConn() {
		try {
			//如果連線池為空或者被異常關閉,則重新初始化一個
			if(pool == null || pool.isClosed()) {
				init();
			}
			return pool.getConnection();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
		
	}
	
	

	/**
	 * 資源關閉
	 * 
	 * @param stmt
	 * @param conn
	 */
	public static void close(Statement stmt, Connection conn) {
		try {
			if (stmt != null) {
				stmt.close();
			}
			if (conn != null) {
				conn.close();
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 封裝通用的更新操作,對所有更新(INSERT,UPDATE,DELETE)有關的操作都能通過該方法實現
	 * 
	 * @param sql
	 * @return
	 * 
	 */
	public static boolean exeUpdate(Connection conn,String sql, Object... obj) {
		PreparedStatement ps = null;
		try {
			ps = conn.prepareStatement(sql);
			for (int i = 0; i < obj.length; i++) {
				ps.setObject(i + 1, obj[i]);
			}
			return ps.executeUpdate() > 0;
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			close(ps, null);
		}
		return false;
	}

	/**
	 * 技術引數: 泛型,集合框架,反射,JDBC 封裝通用查詢多條及操作
	 * 
	 * @param t
	 * @param sql
	 * @param params
	 * @return
	 */
	public static <T> List<T> queryList(Class<T> t, String sql, Object... params) {
		List<T> list = new ArrayList<>();
		T obj = null;
		Connection conn = null;
		PreparedStatement ps = null;
		try {
			conn = getConn();
			ps = conn.prepareStatement(sql);
			for (int i = 0; i < params.length; i++) {
				ps.setObject(i + 1, params[i]);
			}
			ResultSet rs = ps.executeQuery();
			// 獲取插敘結果集中的元資料(獲取列型別,數量以及長度等資訊)
			ResultSetMetaData rsmd = rs.getMetaData();
			// 宣告一個map集合,用於臨時儲存查詢到的一條資料(key:列名;value:列值)
			Map<String, Object> map = new HashMap<>();
			// 遍歷結果集
			while (rs.next()) {
				// 防止快取上一條資料
				map.clear();
				// 遍歷所有的列
				for (int i = 0; i < rsmd.getColumnCount(); i++) {
					// 獲取列名
					String cname = rsmd.getColumnLabel(i + 1);
					//獲取列型別的int表示形式,以及列型別名稱
//					System.out.println("列型別:"+rsmd.getColumnType(i + 1)+"----"+rsmd.getColumnTypeName(i+1));
					// 獲取列值
					Object value = rs.getObject(cname);
					// 將列明與列值儲存到map中
					map.put(cname, value);
				}
				// 利用反射將map中的資料注入到Java物件中,並將物件存入集合
				if (!map.isEmpty()) {
					// 獲取map集合鍵集(列名集合)
					Set<String> columnNames = map.keySet();
					// 建立物件
					obj = t.newInstance();//new Student() //java.lang.Object
					for (String column : columnNames) {
						// 根據鍵獲取值
						Object value = map.get(column);
						//當資料物件不為空時,才注入資料到屬性中
						if(Objects.nonNull(value)){	
							// 獲取屬性物件
							Field f = t.getDeclaredField(column);
							// 設定屬性為可訪問狀態
							f.setAccessible(true);
							// 為屬性設定
							f.set(obj, value);
						}
					}
					list.add(obj);
				}
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (NoSuchFieldException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		}
		return list;
	}

	/**
	 * 封裝查詢單個物件的方法
	 * 
	 * @param t
	 * @param sql
	 * @param params
	 * @return
	 */
	public static <T> T queryOne(Class<T> t, String sql, Object... params) {
		T obj = null;
		Connection conn = null;
		PreparedStatement ps = null;
		try {
			conn = getConn();
			ps = conn.prepareStatement(sql);
			for (int i = 0; i < params.length; i++) {
				ps.setObject(i + 1, params[i]);
			}
			ResultSet rs = ps.executeQuery();
			ResultSetMetaData rsmd = rs.getMetaData();
			//ORM操作(物件關係對映)
			if (rs.next()) {
				// 建立一個指定型別的例項物件(必須包含預設構造器)
				obj = t.newInstance();
				for (int i = 0; i < rsmd.getColumnCount(); i++) {
					//獲取指定列的列名稱
					String cname = rsmd.getColumnLabel(i + 1);
					//獲取列值
					Object value = rs.getObject(cname);
					if(Objects.nonNull(value)){						
						//根據列名稱獲取Java類的屬性名(要求表中的列名稱必須與類中的屬性名保持一致)
						Field field = t.getDeclaredField(cname);
						//將欄位設定為可訪問狀態
						field.setAccessible(true);
						//為欄位設定屬性值
						field.set(obj, value);
					}
				}
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (NoSuchFieldException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		}
		return obj;
	}
	
}

相關推薦

基於Druid連線JDBC基礎框架

JDBC連線池         對於大多數應用程式,當它們正在處理通常需要數毫秒完成的事務時,僅需要能夠訪問JDBC連線的 1 個執行緒。當不處理事務時,這個連線就會閒置。相反,連線池允許閒置的連線被其它需要的執行緒使用。         事實上,當一個執行緒需要用 JD

Spring框架中JdbcTemplate類的查表功能演示(基於Druid連線)

    將資料庫行記錄轉為已知類的實現物件的思路,作為一個java後端程式設計師的基本修養,必須掌握,現舉其中一例: 步驟: 1.首先需要配置 Druid(阿里巴巴) 連線池環境,寫好工具類JDBCUtilsDruid,不再贅述; 2.配置Spring框架環

spring jdbc --注:c3p0資料庫連線druid連線使用配置整理

是Maven配置檔案:pom.xml的程式碼內容: <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:sch

idea配置阿里Druid資料連線在SSM框架中使用

阿里Druid資料連線池在SSM框架中的配置使用 一、Druid資料連線池簡介 Druid是Java語言中最好的資料庫連線池。Druid能夠提供強大的監控和擴充套件功能。 效能好,同時自帶監控頁面,可以實時監控應用的連線池情況以及其中效能差的sql,方便我們找出應用中連線池方面的問題。

JDBC第四篇--【資料庫連線、DbUtils框架、分頁】

1.資料庫連線池 什麼是資料庫連線池 簡單來說:資料庫連線池就是提供連線的。 為什麼我們要使用資料庫連線池 資料庫的連線的建立和關閉是非常消耗資源的 頻繁地開啟、關閉連線造成系統性能低下 編寫連線池 編寫連線池需實現java.sql

引入阿里Druid資料庫連線(maven ssm框架)

Druid Druid是阿里巴巴開源平臺上的一個專案,整個專案由資料庫連線池、外掛框架和SQL解析器組成。該專案主要是為了擴充套件JDBC的一些限制,可以讓程式設計師實現一些特殊的需求,比如向金鑰服務請求憑證、統計SQL資訊、SQL效能收集、SQL注入檢查、S

SpringBoot框架:通過AOP和自定義註解完成druid連線的動態資料來源切換(三)

一、引入依賴   引入資料庫連線池的依賴——druid和麵向切面程式設計的依賴——aop,如下所示: <!-- druid --> <dependency> <groupId

某互聯網上市公司基於 Golang 的運維基礎框架

golang 架構 運維 主題:某互聯網上市公司基於 Golang 的運維基礎框架 目錄 服務器監控系統 自動化部署系統 功能展示 高可用控制系統的演化 高可用調度系統 資源定位系統 整體架構 強一致,高可用設計 一點兒心得 主講師:PC 豆瓣、百度、360

SpringBoot2.x預設連線hikari及druid連線

    在SpringBoot2.x的預設連線池是hikari。我們可以通過spring-boot-starter-jdbc的依賴發現。但是HikariCP應該是目前速度最快的連線池了。 1.hikari連線池使用 pom.xml中jdbc的三座標 <depen

DRUID 連線的實用 配置詳解

DRUID介紹     DRUID是阿里巴巴開源平臺上一個資料庫連線池實現,它結合了C3P0、DBCP、PROXOOL等DB池的優點,同時加入了日誌監控,可以很好的監控DB池連線和SQL的執行情況,可以說是針對監控而生的DB連線池(據說是目前最好的連線

Spring boot 整合druid連線

前言 Druid是一個關係型資料庫連線池,是阿里巴巴的一個開源專案 地址:https://github.com/alibaba/druid Druid不但提供連線池的功能,還提供監控功能,可以實時檢視資料庫連線池和SQL查詢的工作情況。 配置Druid依賴 <!--web

SpringBoot整合Druid連線,Caused by: java.lang.ClassNotFoundException: org.apache.log4j

github:https://github.com/alibaba/druid SpringBoot版本:1.5.9.RELEASE   預設使用的日誌框架為log4j2 在配置 Druid 資料監控時,進行了如下配置 # 配置監控統計攔截的filters,去掉後

SpringBoot入門篇--整合mybatis+generator自動生成程式碼+druid連線+PageHelper分頁外掛

我們這一一篇部落格講的是如何整合Springboot和Mybatis框架,然後使用generator自動生成mapper,pojo等檔案。然後再使用阿里巴巴提供的開源連線池druid,這個連線池的好處我就不說了,集合了所有連線池的好處,並且還提供了監控等功能,加大了可擴充套件性等等。   1.&

Sping boot加入Druid連線異常之Error creating bean with name 'dataSource'

配置Druid資料連線池之後一直報錯找不到資料來源 org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userController': Unsatisf

Druid連線-配置_DruidDataSource參考配置

【更多參考】https://www.cnblogs.com/niejunlei/p/5977895.html 配置_DruidDataSource參考配置 以下是一個參考的連線池配置: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

Mybatis配置C3p0 和Druid連線

普通java工程配置Mybatis 連線池 整體結構 匯入jar 包: 連結:https://pan.baidu.com/s/1aEpDPO9xRK1_shVsUpOEZA 提取碼:16nf Mybatis 配置檔案: <?xml version="

1112_maven專案使用Druid連線配置步驟和注意事項[mysql資料庫]

maven專案使用Druid連線池配置步驟和注意事項[mysql資料庫] 2018年06月13日 17:09:25 個人分類: java 注:這兩天搭建專案時,使用Druid連線池入了不少坑;以此記錄; MySQL Server 5.7.21 + mysql-connector-j

druid連線使用記錄

                         

Druid連線Oracle版本衝突報錯

使用Druid連線池進行Oracle插入資料時,有時成功,有時失敗,成功率基本維持為50%左右,這種非完全失敗的情況令人挺鬱悶的,報錯內容如下: java.sql.SQLException: Closed Statement at oracle.jdbc.driver.OracleClosedS

Druid連線-配置監控介面

一、前言       在阿里的資料庫連線池中,Druid是一個很好的選擇。她可以實現程式設計師的一些特殊的需求,比如像金鑰服務請求憑證,統計sql資訊,sql效能收集,sql注入檢測,sql翻譯等。   &nbs