資料庫連線池的原理與實現(詳解)
阿新 • • 發佈:2019-01-07
資料庫連線池類的設計
類1:資料庫連線池類DBconnctionPool
屬性:
inuserd 當前正在使用的連線數(int 型別)
maxConn 最大的連線數(int 型別)
minConn 最小的連線數(int 型別)
poolName 連線池的名稱(String 型別)
ArrayList freeConnections=new ArrayList() (容器,用來裝空閒的連線)
username 使用者名稱(String型別)
password 密碼(String 型別)
url 連線的地址(String 型別)
driver 驅動(String型別)
方法:
1.構造方法
//構造器函式
public DBconnctionPool(int maxConn, String username, String password,
String url, String driver) {
super();
this.maxConn = maxConn;
this.username = username;
this.password = password;
this.url = url;
this.driver = driver;
}
2.用完釋放連線的方法
public synchronized void freeConnection(Connection conn){
freeConnections.add(conn);
inuserd--;
}
3.建立新連線的方法
public Connection createConnection() {
Connection conn = null;
try {
Class.forName(driver);
conn = DriverManager.getConnection(url, username, password);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("sorry,can't find the driver");
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("can't connect...");
}
return conn;
}
4.從連線池得到連線的方法
public synchronized Connection getConnection()
{
Connection con=null;
if(this.freeConnections.size()>0)
{
con=(Connection)this.freeConnections.get(0);
this.freeConnections.remove(0);//如果連線分配出去了,就從空閒連線裡刪除
if(con==null)con=getConnection(); //繼續獲得連線
}
else
{
con=newConnection(); //新建連線
}
if(this.maxConn==0||this.maxConn<this.inUsed)
{
con=null;//等待 超過最大連線時
}
if(con!=null)
{
this.inUsed++;
System.out.println("得到 "+this.name+" 的連線,現有"+inUsed+"個連線在使用!");
}
return con;
}
5.釋放所有空閒連線的方法
public synchronized void release(){
Iterator allconns=freeConnections.iterator();
while(allconns.hasNext()){
Connection conn=(Connection) allconns.next();
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//移除集合裡的所有元素
freeConnections.clear();
}
類2:資料庫連線池管理類
package com.crm.util.pool;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
/**
* 資料庫連線池管理類
* @author abcd
*
*/
public class DBconnectionManager {
public int clients;//客戶的連線數
static private DBconnectionManager instance;//唯一的連線池管理類例項
HashMap<String,DBconnctionPool> connectPools=new HashMap<String,DBconnctionPool>();
ArrayList<DsconfigBean> drivers=new ArrayList<DsconfigBean>();//bean類集合
/**
* 利用單例模式保證取得唯一的連線池管理類例項
* @return
*/
static public DBconnectionManager getInstance(){
if(instance==null){
instance=new DBconnectionManager();
}
return instance;
}
/**
* 建立連線池
* @param bean
*/
public void createPool(DsconfigBean bean){
DBconnctionPool pool=new DBconnctionPool();
System.out.println(bean.getName());
pool.setDriver(bean.getDriver());
pool.setMaxConn(bean.getMaxCount());
pool.setPassword(bean.getPassword());
pool.setPoolName(bean.getName());
pool.setUrl(bean.getUrl());
pool.setUsername(bean.getUsername());
connectPools.put(bean.getName(), pool);
}
/**
* 載入驅動程式
*/
public void loadDrivers(){
ParseConfig oaConfig=new ParseConfig();
drivers=oaConfig.ReadConfig();
}
/**
* 初始化連線池引數
* 1.呼叫類讀取配置檔案
* 2.把讀取到的有關driver的資訊儲存在集合drivers裡
*/
public void init(){
loadDrivers();
//遍歷迭代建立相應的連線池
DsconfigBean myBean=new DsconfigBean();
for(int i=0;i<drivers.size();i++){
myBean=drivers.get(i);
createPool(myBean);
}
}
/**
* 根據連線池的名字得到一個連線
* @param name
* @return
*/
public Connection getConnection(String name){
DBconnctionPool pool=null;
Connection conn=null;
pool=(DBconnctionPool)connectPools.get(name);
conn=pool.getConnection();
return conn;
}
}
類3:配置檔案對應的bean類
package com.crm.util.pool;
/**
* 配置檔案Bean類
* @author abcd
*
*/
public class DsconfigBean {
private String name;//資料庫名字
private String type;//連線池型別
private String driver;//連線池驅動
private String url;//連線池地址
private String username;//使用者名稱
private String password;//密碼
private int maxCount;//最大連線數
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getDriver() {
return driver;
}
public void setDriver(String driver) {
this.driver = driver;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getMaxCount() {
return maxCount;
}
public void setMaxCount(int maxCount) {
this.maxCount = maxCount;
}
}
類4:解析新增配置檔案的類
package com.crm.util.pool;
import java.util.ArrayList;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;
/**
* 操作配置檔案的類
* @author abcd
*
*/
public class ParseConfig {
/**
* 利用dom4j包讀取配置檔案內容返回集合beans
* @return
*/
public ArrayList<DsconfigBean> ReadConfig(){
ArrayList<DsconfigBean> beans=new ArrayList<DsconfigBean>();
//得到解析器
SAXReader saxReader=new SAXReader();
//設定ErrorHander
saxReader.setErrorHandler(new DefaultHandler(){
public void error(SAXParseException ex){
System.out.println(ex.getSystemId()+"文件的第"+ex.getLineNumber()+"行,第"+
ex.getColumnNumber()+"列"+"發生錯誤"+ex.getMessage());
}
});
//建立樹形結構開始解析
try {
Document document=saxReader.read("dsconfig.xml");
Element root=document.getRootElement();//得到根節點
//獲得所有的pool下的節點
List<Node> nodes=document.selectNodes("ds-config/pool");
//System.out.println(nodes.size());
//遍歷節點
for (Node node : nodes) {
DsconfigBean dsconfigBean=new DsconfigBean();
Node node1=node.selectSingleNode("driver");
Node node2=node.selectSingleNode("username");
Node node3=node.selectSingleNode("password");
Node node4=node.selectSingleNode("url");
Node node5=node.selectSingleNode("maxconn");
Node node6=node.selectSingleNode("type");
dsconfigBean.setDriver(node1.getStringValue());
dsconfigBean.setUsername(node2.getStringValue());
dsconfigBean.setPassword(node3.getStringValue());
dsconfigBean.setUrl(node4.getStringValue());
dsconfigBean.setMaxCount(Integer.valueOf(node5.getStringValue()));
dsconfigBean.setName(node6.getStringValue());
beans.add(dsconfigBean);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return beans;
}
}
5.配置檔案dsconfig.xml
<?xml version="1.0" encoding="UTF-8"?>
<ds-config>
<pool>
<type>mysql</type>
<name>user</name>
<driver>com.mysql.jdbc.driver</driver>
<url>jdbc:mysql://localhost:3306/user</url>
<username>sa</username>
<password>123456</password>
<maxconn>100</maxconn>
</pool>
<pool>
<type>mysql</type>
<name>user2</name>
<driver>com.mysql.jdbc.driver</driver>
<url>jdbc:mysql://localhost:3306/user2</url>
<username>sa</username>
<password>1234</password>
<maxconn>10</maxconn>
</pool>
<pool>
<type>sqlserver</type>
<name>books</name>
<driver>com.microsoft.sqlserver.jdbc.SQLServerDriver</driver>
<url>jdbc:sqlserver://localhost:1433;DatabaseName=GZLCRM</url>
<username>sa</username>
<password>123</password>
<maxconn>100</maxconn>
</pool>
</ds-config>
6.測試類DBTest
package com.crm.util.pool;
import java.sql.Connection;
/**
* 測試連線池的類
* @author abcd
*
*/
public class DBTest {
public static void main(String[] args) {
DBconnectionManager manager=DBconnectionManager.getInstance();
manager.init();
Connection connection=manager.getConnection("sqlserver");
System.out.println(connection.toString());
}
}
類1:資料庫連線池類DBconnctionPool
屬性:
inuserd 當前正在使用的連線數(int 型別)
maxConn 最大的連線數(int 型別)
minConn 最小的連線數(int 型別)
poolName 連線池的名稱(String 型別)
ArrayList freeConnections=new ArrayList() (容器,用來裝空閒的連線)
username 使用者名稱(String型別)
password 密碼(String 型別)
url 連線的地址(String 型別)
driver 驅動(String型別)
方法:
1.構造方法
//構造器函式
public DBconnctionPool(int maxConn, String username, String password,
String url, String driver) {
super();
this.maxConn = maxConn;
this.username = username;
this.password = password;
this.url = url;
this.driver = driver;
}
2.用完釋放連線的方法
public synchronized void freeConnection(Connection conn){
freeConnections.add(conn);
inuserd--;
}
3.建立新連線的方法
public Connection createConnection() {
Connection conn = null;
try {
Class.forName(driver);
conn = DriverManager.getConnection(url, username, password);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("sorry,can't find the driver");
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("can't connect...");
}
return conn;
}
4.從連線池得到連線的方法
public synchronized Connection getConnection()
{
Connection con=null;
if(this.freeConnections.size()>0)
{
con=(Connection)this.freeConnections.get(0);
this.freeConnections.remove(0);//如果連線分配出去了,就從空閒連線裡刪除
if(con==null)con=getConnection(); //繼續獲得連線
}
else
{
con=newConnection(); //新建連線
}
if(this.maxConn==0||this.maxConn<this.inUsed)
{
con=null;//等待 超過最大連線時
}
if(con!=null)
{
this.inUsed++;
System.out.println("得到 "+this.name+" 的連線,現有"+inUsed+"個連線在使用!");
}
return con;
}
5.釋放所有空閒連線的方法
public synchronized void release(){
Iterator allconns=freeConnections.iterator();
while(allconns.hasNext()){
Connection conn=(Connection) allconns.next();
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//移除集合裡的所有元素
freeConnections.clear();
}
類2:資料庫連線池管理類
package com.crm.util.pool;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
/**
* 資料庫連線池管理類
* @author abcd
*
*/
public class DBconnectionManager {
public int clients;//客戶的連線數
static private DBconnectionManager instance;//唯一的連線池管理類例項
HashMap<String,DBconnctionPool> connectPools=new HashMap<String,DBconnctionPool>();
ArrayList<DsconfigBean> drivers=new ArrayList<DsconfigBean>();//bean類集合
/**
* 利用單例模式保證取得唯一的連線池管理類例項
* @return
*/
static public DBconnectionManager getInstance(){
if(instance==null){
instance=new DBconnectionManager();
}
return instance;
}
/**
* 建立連線池
* @param bean
*/
public void createPool(DsconfigBean bean){
DBconnctionPool pool=new DBconnctionPool();
System.out.println(bean.getName());
pool.setDriver(bean.getDriver());
pool.setMaxConn(bean.getMaxCount());
pool.setPassword(bean.getPassword());
pool.setPoolName(bean.getName());
pool.setUrl(bean.getUrl());
pool.setUsername(bean.getUsername());
connectPools.put(bean.getName(), pool);
}
/**
* 載入驅動程式
*/
public void loadDrivers(){
ParseConfig oaConfig=new ParseConfig();
drivers=oaConfig.ReadConfig();
}
/**
* 初始化連線池引數
* 1.呼叫類讀取配置檔案
* 2.把讀取到的有關driver的資訊儲存在集合drivers裡
*/
public void init(){
loadDrivers();
//遍歷迭代建立相應的連線池
DsconfigBean myBean=new DsconfigBean();
for(int i=0;i<drivers.size();i++){
myBean=drivers.get(i);
createPool(myBean);
}
}
/**
* 根據連線池的名字得到一個連線
* @param name
* @return
*/
public Connection getConnection(String name){
DBconnctionPool pool=null;
Connection conn=null;
pool=(DBconnctionPool)connectPools.get(name);
conn=pool.getConnection();
return conn;
}
}
類3:配置檔案對應的bean類
package com.crm.util.pool;
/**
* 配置檔案Bean類
* @author abcd
*
*/
public class DsconfigBean {
private String name;//資料庫名字
private String type;//連線池型別
private String driver;//連線池驅動
private String url;//連線池地址
private String username;//使用者名稱
private String password;//密碼
private int maxCount;//最大連線數
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getDriver() {
return driver;
}
public void setDriver(String driver) {
this.driver = driver;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getMaxCount() {
return maxCount;
}
public void setMaxCount(int maxCount) {
this.maxCount = maxCount;
}
}
類4:解析新增配置檔案的類
package com.crm.util.pool;
import java.util.ArrayList;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;
/**
* 操作配置檔案的類
* @author abcd
*
*/
public class ParseConfig {
/**
* 利用dom4j包讀取配置檔案內容返回集合beans
* @return
*/
public ArrayList<DsconfigBean> ReadConfig(){
ArrayList<DsconfigBean> beans=new ArrayList<DsconfigBean>();
//得到解析器
SAXReader saxReader=new SAXReader();
//設定ErrorHander
saxReader.setErrorHandler(new DefaultHandler(){
public void error(SAXParseException ex){
System.out.println(ex.getSystemId()+"文件的第"+ex.getLineNumber()+"行,第"+
ex.getColumnNumber()+"列"+"發生錯誤"+ex.getMessage());
}
});
//建立樹形結構開始解析
try {
Document document=saxReader.read("dsconfig.xml");
Element root=document.getRootElement();//得到根節點
//獲得所有的pool下的節點
List<Node> nodes=document.selectNodes("ds-config/pool");
//System.out.println(nodes.size());
//遍歷節點
for (Node node : nodes) {
DsconfigBean dsconfigBean=new DsconfigBean();
Node node1=node.selectSingleNode("driver");
Node node2=node.selectSingleNode("username");
Node node3=node.selectSingleNode("password");
Node node4=node.selectSingleNode("url");
Node node5=node.selectSingleNode("maxconn");
Node node6=node.selectSingleNode("type");
dsconfigBean.setDriver(node1.getStringValue());
dsconfigBean.setUsername(node2.getStringValue());
dsconfigBean.setPassword(node3.getStringValue());
dsconfigBean.setUrl(node4.getStringValue());
dsconfigBean.setMaxCount(Integer.valueOf(node5.getStringValue()));
dsconfigBean.setName(node6.getStringValue());
beans.add(dsconfigBean);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return beans;
}
}
5.配置檔案dsconfig.xml
<?xml version="1.0" encoding="UTF-8"?>
<ds-config>
<pool>
<type>mysql</type>
<name>user</name>
<driver>com.mysql.jdbc.driver</driver>
<url>jdbc:mysql://localhost:3306/user</url>
<username>sa</username>
<password>123456</password>
<maxconn>100</maxconn>
</pool>
<pool>
<type>mysql</type>
<name>user2</name>
<driver>com.mysql.jdbc.driver</driver>
<url>jdbc:mysql://localhost:3306/user2</url>
<username>sa</username>
<password>1234</password>
<maxconn>10</maxconn>
</pool>
<pool>
<type>sqlserver</type>
<name>books</name>
<driver>com.microsoft.sqlserver.jdbc.SQLServerDriver</driver>
<url>jdbc:sqlserver://localhost:1433;DatabaseName=GZLCRM</url>
<username>sa</username>
<password>123</password>
<maxconn>100</maxconn>
</pool>
</ds-config>
6.測試類DBTest
package com.crm.util.pool;
import java.sql.Connection;
/**
* 測試連線池的類
* @author abcd
*
*/
public class DBTest {
public static void main(String[] args) {
DBconnectionManager manager=DBconnectionManager.getInstance();
manager.init();
Connection connection=manager.getConnection("sqlserver");
System.out.println(connection.toString());
}
}