高并发高效数据库连接池

 来源:http://www.lcfms.cn:81/


/*
 * 高并发高效数据库连接池
 * 作者:老成 http://www.lcfms.cn:81/
 */
package com.bin;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;


import com.mysql.jdbc.Statement;


public class Db {
// 定义数据库物理地址
private String HOST;
// 定义数据库用户名
private String USERNAME;
// 定义数据库密码
private String PASSWORD;
// 定义数据库驱动信息
private String DRIVER ;
//交换连接池
private static Set<Connection> conn_pools;
//连接池中被激活的连接数量
private int connNum;


public Db(HashMap<String, Object> config) throws Exception{
if(config.get("type").equals("mysql")){
this.DRIVER="com.mysql.jdbc.Driver";
}
if(config.get("type").equals("mssql")){
this.DRIVER="com.microsoft.sqlserver.jdbc.SQLServerDriver";
}
this.HOST=(String)config.get("host");
this.USERNAME=(String)config.get("username");
this.PASSWORD=(String)config.get("password");
this.connNum=(int) config.get("connNum");
try {
Class.forName(DRIVER);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 创建数据库连接池
* @param i 连接池中连接数量
*/
public void createPools() throws SQLException{
if(conn_pools==null){
conn_pools = new HashSet<Connection>(connNum);  
       for (int i = 0; i < connNum; i++) {
        conn_pools.add(DriverManager.getConnection(HOST, USERNAME, PASSWORD));               
       }     
}               
}
/**
 * 获取一个连接
 * @return
* @throws SQLException 
 */
private  Connection getPoolConn() throws SQLException{
synchronized(this){
Iterator<Connection> iter=conn_pools.iterator();
while (iter.hasNext()) {
Connection conn=iter.next();
conn_pools.remove(conn);
System.out.println(Thread.currentThread().getName()+":取出一个连接,当前还剩"+conn_pools.size()+"个连接");
if(isValid(conn)){
return conn;
}else{
System.out.println(Thread.currentThread().getName()+":连接已经过期,新建连接!");
return DriverManager.getConnection(HOST, USERNAME, PASSWORD);   
}
}
try {
   System.out.println(Thread.currentThread().getName()+":连接池中没有连接了,等待连接中!");
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+":该线程被唤醒!");
return this.getPoolConn();
}  
}
    /**
     * 判断连接是否可用
     * @param conn
     * @return
     */
private boolean isValid(Connection conn) {
try {
if (conn == null || conn.isClosed()) {
return false;
}
} catch (SQLException e) {
e.printStackTrace();
}
return true;
}


/**
* 执行SQL语句,executeUpdate方法可以实现修改,插入,删除语句,如果是插入则返回插入自增的ID,否则返回影响的行数

* @throws SQLException
*/
public HashMap<String,Integer> query(String sql, Object obj) throws SQLException {
HashMap<String,Integer> map=new HashMap<>();
Connection conn=this.getPoolConn();
int index = -1;// 执行SQL影响的行数
// 定义数据库SQL语句的执行对象
PreparedStatement pstate;
if(sql.substring(0,6).equals("insert")){
pstate = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
}else{
pstate = conn.prepareStatement(sql);
}
if(obj instanceof Object[]){
Object[] object=(Object[])obj;
if (object.length >= 1) {
for (int i = 0; i < object.length; i++) {
pstate.setObject(i + 1, object[i]);
}
}
}else if(obj instanceof List){
@SuppressWarnings("unchecked")
List<Object> object=(List<Object>)obj;
if (object.size() >= 1) {
for (int i = 0; i < object.size(); i++) {
pstate.setObject(i + 1,object.get(i));
}
}
}else if(obj!=null){
pstate.setObject(1, obj);
}
int lastinsertid=-1;
index=pstate.executeUpdate();  
        if(index>0 && sql.substring(0,6).equals("insert")) {//记录保存成功  
        ResultSet result=pstate.getGeneratedKeys(); 
            if(result.next()) {
            try {
    lastinsertid=result.getInt(1);
    } catch (Exception e) {
    e.printStackTrace();
    }  
            }            
        }  
        map.put("affectLine", index);
map.put("lastId", lastinsertid);
conn_pools.add(conn);
synchronized(this){
notifyAll();
}
return map;
}


/**
* 执行有返回集的SQL语句,executeQuery方法可以实现查询语句,记录数需求为int

* @throws SQLException
*/
public List<Map<String, Object>> sql(String sql, Object obj)throws SQLException {
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
Connection conn=this.getPoolConn();
// 定义数据库SQL语句的执行对象
PreparedStatement pstate = conn.prepareStatement(sql);
if(obj instanceof Object[]){
Object[] object=(Object[])obj;
if (object.length >= 1) {
for (int i = 0; i < object.length; i++) {
pstate.setObject(i + 1, object[i]);
}
}
}else if(obj instanceof List){
@SuppressWarnings("unchecked")
List<Object> object=(List<Object>)obj;
if (object.size() >= 1) {
for (int i = 0; i < object.size(); i++) {
pstate.setObject(i + 1,object.get(i));
}
}
}else if(obj!=null){
pstate.setObject(1, obj);
}
ResultSet result = pstate.executeQuery();
int column_long = result.getMetaData().getColumnCount();// 获取一行的字段信息
while (result.next()) {
Map<String, Object> map = new HashMap<String, Object>();
for (int i = 0; i < column_long; i++) {
String key = result.getMetaData().getColumnLabel(i + 1);
Object value = result.getObject(key);
if(value instanceof Long){
value=Integer.valueOf(String.valueOf(value));//当需求记录数不大时,将long转换为int方便计算
}
if (value == null) {
value = "";
}
map.put(key, value);
}
list.add(map);
}
result.close();
conn_pools.add(conn);
synchronized(this){
notifyAll();
}
return list;
}
/**
* 关闭数据库链接
*/
public void closejdbc(Connection conn) {
try {
if (conn.isClosed() != true)
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//测试场景
public static void main(String[] args) throws Exception{
HashMap<String, Object> config=new HashMap<String, Object>();
config.put("type", "mysql");
config.put("host", "jdbc:mysql://localhost:3306/qyweixin?characterEncoding=utf-8");
config.put("username", "dbuser");
config.put("password", "Dbu!50Us");
config.put("prefix", "laocheng_");
config.put("connNum", 5);
Db db=new Db(config);
db.createPools();
for(int i=0;i<10;i++){
Factory factory=new Factory(db);
Thread thread = new Thread(factory);  
thread.start();  
}
}
}
/**
 * 多线程测试类
 * @author Administrator
 *
 */
class Factory implements Runnable{
private Db db;
Factory(Db db){
this.db=db;
}
public void run() {
for(int i=0;i<5;i++){
try {
this.db.query("insert into laocheng_test (test) values (?) ", i);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
/**测试结果如下
Thread-5:连接池中没有连接了,等待连接中!
Thread-11:连接池中没有连接了,等待连接中!
Thread-9:连接池中没有连接了,等待连接中!
Thread-7:连接池中没有连接了,等待连接中!
Thread-2:取出一个连接,当前还剩0个连接
Thread-7:该线程被唤醒!
Thread-7:连接池中没有连接了,等待连接中!
Thread-9:该线程被唤醒!
Thread-9:连接池中没有连接了,等待连接中!
Thread-11:该线程被唤醒!
Thread-11:连接池中没有连接了,等待连接中!
Thread-5:该线程被唤醒!
Thread-5:连接池中没有连接了,等待连接中!
Thread-3:该线程被唤醒!
Thread-3:连接池中没有连接了,等待连接中!
Thread-4:取出一个连接,当前还剩1个连接
Thread-8:取出一个连接,当前还剩1个连接
Thread-3:该线程被唤醒!
Thread-3:取出一个连接,当前还剩0个连接
Thread-5:该线程被唤醒!
Thread-5:取出一个连接,当前还剩0个连接
Thread-11:该线程被唤醒!
Thread-11:连接池中没有连接了,等待连接中!
Thread-9:该线程被唤醒!
Thread-9:连接池中没有连接了,等待连接中!
Thread-7:该线程被唤醒!
Thread-7:连接池中没有连接了,等待连接中!
Thread-6:连接池中没有连接了,等待连接中!
Thread-10:连接池中没有连接了,等待连接中!
Thread-7:该线程被唤醒!
Thread-7:连接池中没有连接了,等待连接中!
Thread-9:该线程被唤醒!
Thread-9:连接池中没有连接了,等待连接中!
Thread-11:该线程被唤醒!
Thread-11:连接池中没有连接了,等待连接中!
Thread-2:取出一个连接,当前还剩0个连接
Thread-11:该线程被唤醒!
Thread-11:连接池中没有连接了,等待连接中!
Thread-9:该线程被唤醒!
Thread-9:连接池中没有连接了,等待连接中!
Thread-7:该线程被唤醒!
Thread-7:连接池中没有连接了,等待连接中!
Thread-10:该线程被唤醒!
Thread-10:连接池中没有连接了,等待连接中!
Thread-6:该线程被唤醒!
Thread-6:连接池中没有连接了,等待连接中!
Thread-8:取出一个连接,当前还剩0个连接
Thread-4:取出一个连接,当前还剩0个连接
Thread-5:取出一个连接,当前还剩0个连接
Thread-6:该线程被唤醒!
Thread-6:连接池中没有连接了,等待连接中!
Thread-10:该线程被唤醒!
Thread-10:连接池中没有连接了,等待连接中!
Thread-3:取出一个连接,当前还剩0个连接
Thread-7:该线程被唤醒!
Thread-7:连接池中没有连接了,等待连接中!
Thread-9:该线程被唤醒!
Thread-9:连接池中没有连接了,等待连接中!
Thread-11:该线程被唤醒!
Thread-11:连接池中没有连接了,等待连接中!
Thread-10:该线程被唤醒!
Thread-10:连接池中没有连接了,等待连接中!
Thread-6:该线程被唤醒!
Thread-6:连接池中没有连接了,等待连接中!
Thread-8:取出一个连接,当前还剩0个连接
Thread-6:该线程被唤醒!
Thread-6:连接池中没有连接了,等待连接中!
Thread-10:该线程被唤醒!
Thread-10:连接池中没有连接了,等待连接中!
Thread-11:该线程被唤醒!
Thread-11:连接池中没有连接了,等待连接中!
Thread-9:该线程被唤醒!
Thread-9:连接池中没有连接了,等待连接中!
Thread-7:该线程被唤醒!
Thread-7:连接池中没有连接了,等待连接中!
Thread-2:取出一个连接,当前还剩0个连接
Thread-7:该线程被唤醒!
Thread-7:连接池中没有连接了,等待连接中!
Thread-9:该线程被唤醒!
Thread-9:连接池中没有连接了,等待连接中!
Thread-11:该线程被唤醒!
Thread-11:连接池中没有连接了,等待连接中!
Thread-10:该线程被唤醒!
Thread-10:连接池中没有连接了,等待连接中!
Thread-6:该线程被唤醒!
Thread-6:连接池中没有连接了,等待连接中!
Thread-4:取出一个连接,当前还剩0个连接
Thread-6:该线程被唤醒!
Thread-6:连接池中没有连接了,等待连接中!
Thread-10:该线程被唤醒!
Thread-10:连接池中没有连接了,等待连接中!
Thread-3:取出一个连接,当前还剩0个连接
Thread-5:取出一个连接,当前还剩0个连接
Thread-11:该线程被唤醒!
Thread-11:连接池中没有连接了,等待连接中!
Thread-9:该线程被唤醒!
Thread-9:连接池中没有连接了,等待连接中!
Thread-7:该线程被唤醒!
Thread-7:连接池中没有连接了,等待连接中!
Thread-10:该线程被唤醒!
Thread-10:连接池中没有连接了,等待连接中!
Thread-6:该线程被唤醒!
Thread-6:连接池中没有连接了,等待连接中!
Thread-8:取出一个连接,当前还剩0个连接
Thread-6:该线程被唤醒!
Thread-6:连接池中没有连接了,等待连接中!
Thread-10:该线程被唤醒!
Thread-10:连接池中没有连接了,等待连接中!
Thread-7:该线程被唤醒!
Thread-7:连接池中没有连接了,等待连接中!
Thread-9:该线程被唤醒!
Thread-9:连接池中没有连接了,等待连接中!
Thread-11:该线程被唤醒!
Thread-11:连接池中没有连接了,等待连接中!
Thread-4:取出一个连接,当前还剩0个连接
Thread-11:该线程被唤醒!
Thread-11:连接池中没有连接了,等待连接中!
Thread-9:该线程被唤醒!
Thread-9:连接池中没有连接了,等待连接中!
Thread-7:该线程被唤醒!
Thread-7:连接池中没有连接了,等待连接中!
Thread-10:该线程被唤醒!
Thread-10:连接池中没有连接了,等待连接中!
Thread-6:该线程被唤醒!
Thread-6:连接池中没有连接了,等待连接中!
Thread-2:取出一个连接,当前还剩0个连接
Thread-6:该线程被唤醒!
Thread-6:连接池中没有连接了,等待连接中!
Thread-10:该线程被唤醒!
Thread-10:连接池中没有连接了,等待连接中!
Thread-7:该线程被唤醒!
Thread-7:连接池中没有连接了,等待连接中!
Thread-9:该线程被唤醒!
Thread-9:连接池中没有连接了,等待连接中!
Thread-11:该线程被唤醒!
Thread-11:连接池中没有连接了,等待连接中!
Thread-3:取出一个连接,当前还剩1个连接
Thread-5:取出一个连接,当前还剩1个连接
Thread-11:该线程被唤醒!
Thread-11:取出一个连接,当前还剩0个连接
Thread-9:该线程被唤醒!
Thread-9:连接池中没有连接了,等待连接中!
Thread-7:该线程被唤醒!
Thread-7:连接池中没有连接了,等待连接中!
Thread-10:该线程被唤醒!
Thread-10:连接池中没有连接了,等待连接中!
Thread-6:该线程被唤醒!
Thread-6:连接池中没有连接了,等待连接中!
Thread-6:该线程被唤醒!
Thread-6:取出一个连接,当前还剩0个连接
Thread-10:该线程被唤醒!
Thread-10:连接池中没有连接了,等待连接中!
Thread-7:该线程被唤醒!
Thread-7:连接池中没有连接了,等待连接中!
Thread-9:该线程被唤醒!
Thread-9:连接池中没有连接了,等待连接中!
Thread-11:取出一个连接,当前还剩1个连接
Thread-9:该线程被唤醒!
Thread-9:取出一个连接,当前还剩0个连接
Thread-7:该线程被唤醒!
Thread-7:连接池中没有连接了,等待连接中!
Thread-10:该线程被唤醒!
Thread-10:连接池中没有连接了,等待连接中!
Thread-3:取出一个连接,当前还剩0个连接
Thread-10:该线程被唤醒!
Thread-10:连接池中没有连接了,等待连接中!
Thread-5:取出一个连接,当前还剩0个连接
Thread-7:该线程被唤醒!
Thread-7:连接池中没有连接了,等待连接中!
Thread-10:该线程被唤醒!
Thread-10:连接池中没有连接了,等待连接中!
Thread-6:取出一个连接,当前还剩0个连接
Thread-10:该线程被唤醒!
Thread-10:连接池中没有连接了,等待连接中!
Thread-7:该线程被唤醒!
Thread-7:连接池中没有连接了,等待连接中!
Thread-9:取出一个连接,当前还剩0个连接
Thread-7:该线程被唤醒!
Thread-7:连接池中没有连接了,等待连接中!
Thread-10:该线程被唤醒!
Thread-10:连接池中没有连接了,等待连接中!
Thread-11:取出一个连接,当前还剩0个连接
Thread-10:该线程被唤醒!
Thread-10:连接池中没有连接了,等待连接中!
Thread-7:该线程被唤醒!
Thread-7:连接池中没有连接了,等待连接中!
Thread-7:该线程被唤醒!
Thread-7:取出一个连接,当前还剩1个连接
Thread-10:该线程被唤醒!
Thread-10:取出一个连接,当前还剩0个连接
Thread-9:取出一个连接,当前还剩0个连接
Thread-6:取出一个连接,当前还剩0个连接
Thread-10:取出一个连接,当前还剩0个连接
Thread-11:取出一个连接,当前还剩0个连接
Thread-6:取出一个连接,当前还剩0个连接
Thread-7:取出一个连接,当前还剩0个连接
Thread-9:取出一个连接,当前还剩0个连接
Thread-7:取出一个连接,当前还剩1个连接
Thread-10:取出一个连接,当前还剩1个连接
Thread-11:取出一个连接,当前还剩1个连接
Thread-9:取出一个连接,当前还剩1个连接
Thread-10:取出一个连接,当前还剩1个连接
Thread-7:取出一个连接,当前还剩0个连接
Thread-7:取出一个连接,当前还剩3个连接
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值