/* * 高并发高效数据库连接池 * 作者:老成 www.lcfms.cn */ 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/laocheng?characterEncoding=utf-8"); config.put("username", "root"); config.put("password", ""); 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-2:取出一个连接,当前还剩4个连接 Thread-3:取出一个连接,当前还剩3个连接 Thread-5:取出一个连接,当前还剩2个连接 Thread-7:取出一个连接,当前还剩1个连接 Thread-9:取出一个连接,当前还剩0个连接 Thread-11:连接池中没有连接了,等待连接中! Thread-4:连接池中没有连接了,等待连接中! Thread-6:连接池中没有连接了,等待连接中! Thread-8:连接池中没有连接了,等待连接中! Thread-10:连接池中没有连接了,等待连接中! Thread-5:取出一个连接,当前还剩0个连接 Thread-10:该线程被唤醒! Thread-10:连接池中没有连接了,等待连接中! Thread-8:该线程被唤醒! Thread-8:连接池中没有连接了,等待连接中! Thread-6:该线程被唤醒! Thread-6:连接池中没有连接了,等待连接中! Thread-4:该线程被唤醒! Thread-4:连接池中没有连接了,等待连接中! Thread-11:该线程被唤醒! Thread-11:连接池中没有连接了,等待连接中! Thread-7:取出一个连接,当前还剩1个连接 Thread-3:取出一个连接,当前还剩1个连接 Thread-2:取出一个连接,当前还剩1个连接 Thread-11:该线程被唤醒! Thread-11:取出一个连接,当前还剩0个连接 Thread-4:该线程被唤醒! Thread-4:连接池中没有连接了,等待连接中! Thread-6:该线程被唤醒! Thread-6:连接池中没有连接了,等待连接中! Thread-8:该线程被唤醒! Thread-8:连接池中没有连接了,等待连接中! Thread-10:该线程被唤醒! Thread-10:连接池中没有连接了,等待连接中! Thread-9:连接池中没有连接了,等待连接中! Thread-11:取出一个连接,当前还剩0个连接 Thread-9:该线程被唤醒! Thread-9:取出一个连接,当前还剩0个连接 Thread-10:该线程被唤醒! Thread-10:连接池中没有连接了,等待连接中! Thread-8:该线程被唤醒! Thread-8:连接池中没有连接了,等待连接中! Thread-6:该线程被唤醒! Thread-6:连接池中没有连接了,等待连接中! Thread-4:该线程被唤醒! Thread-4:连接池中没有连接了,等待连接中! Thread-5:连接池中没有连接了,等待连接中! Thread-4:该线程被唤醒! Thread-4:连接池中没有连接了,等待连接中! Thread-6:该线程被唤醒! Thread-6:连接池中没有连接了,等待连接中! Thread-8:该线程被唤醒! Thread-8:取出一个连接,当前还剩0个连接 Thread-10:该线程被唤醒! Thread-10:连接池中没有连接了,等待连接中! Thread-7:连接池中没有连接了,等待连接中! Thread-10:该线程被唤醒! Thread-10:连接池中没有连接了,等待连接中! Thread-6:该线程被唤醒! Thread-6:连接池中没有连接了,等待连接中! Thread-4:该线程被唤醒! Thread-4:连接池中没有连接了,等待连接中! Thread-5:该线程被唤醒! Thread-5:连接池中没有连接了,等待连接中! Thread-3:取出一个连接,当前还剩0个连接 Thread-5:该线程被唤醒! Thread-5:连接池中没有连接了,等待连接中! Thread-2:取出一个连接,当前还剩0个连接 Thread-4:该线程被唤醒! Thread-4:连接池中没有连接了,等待连接中! Thread-6:该线程被唤醒! Thread-6:连接池中没有连接了,等待连接中! Thread-10:该线程被唤醒! Thread-10:连接池中没有连接了,等待连接中! Thread-7:该线程被唤醒! Thread-7:连接池中没有连接了,等待连接中! Thread-5:该线程被唤醒! Thread-5:连接池中没有连接了,等待连接中! Thread-11:取出一个连接,当前还剩0个连接 Thread-5:该线程被唤醒! Thread-5:连接池中没有连接了,等待连接中! Thread-7:该线程被唤醒! Thread-7:连接池中没有连接了,等待连接中! Thread-10:该线程被唤醒! Thread-10:连接池中没有连接了,等待连接中! Thread-6:该线程被唤醒! Thread-6:连接池中没有连接了,等待连接中! Thread-4:该线程被唤醒! Thread-4:连接池中没有连接了,等待连接中! Thread-9:取出一个连接,当前还剩0个连接 Thread-4:该线程被唤醒! Thread-4:连接池中没有连接了,等待连接中! Thread-6:该线程被唤醒! Thread-6:连接池中没有连接了,等待连接中! Thread-10:该线程被唤醒! Thread-10:连接池中没有连接了,等待连接中! Thread-7:该线程被唤醒! Thread-7:连接池中没有连接了,等待连接中! Thread-5:该线程被唤醒! Thread-5:连接池中没有连接了,等待连接中! Thread-11:取出一个连接,当前还剩0个连接 Thread-5:该线程被唤醒! Thread-5:连接池中没有连接了,等待连接中! Thread-7:该线程被唤醒! Thread-7:连接池中没有连接了,等待连接中! Thread-3:取出一个连接,当前还剩0个连接 Thread-2:取出一个连接,当前还剩0个连接 Thread-8:取出一个连接,当前还剩0个连接 Thread-10:该线程被唤醒! Thread-10:连接池中没有连接了,等待连接中! Thread-6:该线程被唤醒! Thread-6:连接池中没有连接了,等待连接中! Thread-4:该线程被唤醒! Thread-4:连接池中没有连接了,等待连接中! Thread-7:该线程被唤醒! Thread-7:连接池中没有连接了,等待连接中! Thread-5:该线程被唤醒! Thread-5:连接池中没有连接了,等待连接中! Thread-11:取出一个连接,当前还剩0个连接 Thread-5:该线程被唤醒! Thread-5:连接池中没有连接了,等待连接中! Thread-7:该线程被唤醒! Thread-7:连接池中没有连接了,等待连接中! Thread-4:该线程被唤醒! Thread-4:连接池中没有连接了,等待连接中! Thread-6:该线程被唤醒! Thread-6:连接池中没有连接了,等待连接中! Thread-10:该线程被唤醒! Thread-10:连接池中没有连接了,等待连接中! Thread-8:取出一个连接,当前还剩0个连接 Thread-10:该线程被唤醒! Thread-10:连接池中没有连接了,等待连接中! Thread-6:该线程被唤醒! Thread-6:连接池中没有连接了,等待连接中! Thread-4:该线程被唤醒! Thread-4:连接池中没有连接了,等待连接中! Thread-9:取出一个连接,当前还剩0个连接 Thread-7:该线程被唤醒! Thread-7:连接池中没有连接了,等待连接中! Thread-5:该线程被唤醒! Thread-5:连接池中没有连接了,等待连接中! Thread-4:该线程被唤醒! Thread-4:连接池中没有连接了,等待连接中! Thread-6:该线程被唤醒! Thread-6:连接池中没有连接了,等待连接中! Thread-10:该线程被唤醒! Thread-10:连接池中没有连接了,等待连接中! Thread-3:取出一个连接,当前还剩0个连接 Thread-10:该线程被唤醒! Thread-10:连接池中没有连接了,等待连接中! Thread-6:该线程被唤醒! Thread-6:连接池中没有连接了,等待连接中! Thread-4:该线程被唤醒! Thread-4:连接池中没有连接了,等待连接中! Thread-2:取出一个连接,当前还剩0个连接 Thread-5:该线程被唤醒! Thread-5:连接池中没有连接了,等待连接中! Thread-7:该线程被唤醒! Thread-7:连接池中没有连接了,等待连接中! Thread-4:该线程被唤醒! Thread-4:连接池中没有连接了,等待连接中! Thread-6:该线程被唤醒! Thread-6:连接池中没有连接了,等待连接中! Thread-10:该线程被唤醒! Thread-10:连接池中没有连接了,等待连接中! Thread-8:取出一个连接,当前还剩0个连接 Thread-10:该线程被唤醒! Thread-10:连接池中没有连接了,等待连接中! Thread-6:该线程被唤醒! Thread-6:连接池中没有连接了,等待连接中! Thread-4:该线程被唤醒! Thread-4:连接池中没有连接了,等待连接中! Thread-7:该线程被唤醒! Thread-7:连接池中没有连接了,等待连接中! Thread-5:该线程被唤醒! Thread-5:连接池中没有连接了,等待连接中! Thread-5:该线程被唤醒! Thread-5:取出一个连接,当前还剩0个连接 Thread-7:该线程被唤醒! Thread-7:连接池中没有连接了,等待连接中! Thread-4:该线程被唤醒! Thread-4:连接池中没有连接了,等待连接中! Thread-6:该线程被唤醒! Thread-6:连接池中没有连接了,等待连接中! Thread-10:该线程被唤醒! Thread-10:连接池中没有连接了,等待连接中! Thread-8:取出一个连接,当前还剩0个连接 Thread-9:取出一个连接,当前还剩0个连接 Thread-10:该线程被唤醒! Thread-10:连接池中没有连接了,等待连接中! Thread-6:该线程被唤醒! Thread-6:连接池中没有连接了,等待连接中! Thread-4:该线程被唤醒! Thread-4:连接池中没有连接了,等待连接中! Thread-7:该线程被唤醒! Thread-7:连接池中没有连接了,等待连接中! Thread-7:该线程被唤醒! Thread-7:取出一个连接,当前还剩1个连接 Thread-4:该线程被唤醒! Thread-4:取出一个连接,当前还剩0个连接 Thread-6:该线程被唤醒! Thread-6:连接池中没有连接了,等待连接中! Thread-10:该线程被唤醒! Thread-10:连接池中没有连接了,等待连接中! Thread-5:取出一个连接,当前还剩0个连接 Thread-10:该线程被唤醒! Thread-10:连接池中没有连接了,等待连接中! Thread-6:该线程被唤醒! Thread-6:连接池中没有连接了,等待连接中! Thread-6:该线程被唤醒! Thread-6:取出一个连接,当前还剩0个连接 Thread-10:该线程被唤醒! Thread-10:连接池中没有连接了,等待连接中! Thread-7:取出一个连接,当前还剩0个连接 Thread-10:该线程被唤醒! Thread-10:连接池中没有连接了,等待连接中! Thread-10:该线程被唤醒! Thread-10:取出一个连接,当前还剩0个连接 Thread-4:取出一个连接,当前还剩0个连接 Thread-5:取出一个连接,当前还剩0个连接 Thread-10:取出一个连接,当前还剩0个连接 Thread-6:取出一个连接,当前还剩0个连接 Thread-7:取出一个连接,当前还剩0个连接 Thread-4:取出一个连接,当前还剩0个连接 Thread-6:取出一个连接,当前还剩0个连接 Thread-4:取出一个连接,当前还剩1个连接 Thread-10:取出一个连接,当前还剩2个连接 Thread-6:取出一个连接,当前还剩2个连接 Thread-4:取出一个连接,当前还剩2个连接 Thread-10:取出一个连接,当前还剩2个连接 Thread-6:取出一个连接,当前还剩2个连接 Thread-10:取出一个连接,当前还剩2个连接 */