数据库连接池
想必大家对这个应该已经比较熟悉了吧,数据库连接池在数据库连接上起着不可替代的作用,如果你处理的数据十分巨大的话,那就更显重要了,
以下是一个比较简单的连接池实现(复杂连接池可以查看c3p0的源代码)
1.数据库连接信息接口:
package xidian.xidian.sl.dbconnectpool; /** * 数据库连接信息接口 * 说明:将驱动、连接、数据库名、数据库密码等数据连接基础信息做成接口 * */ public interface IDataBase { /** * @return 数据库驱动名 * 注意必须加入数据库驱动包 * */ public String getDirver(); /** * @return 数据库连接 * */ public String getConnUrl(); /** * @return 数据库用户名 * */ public String getUserName(); /** * @return 数据库密码 * */ public String getPassword(); }
2.数据库连接信息接口实现类
package xidian.xidian.sl.dbconnectpool; /** * 数据库连接信息接口实现类 * @author SeDion * 该类的默认驱动为mysql-connector-java 5.0以上版本 * */ public class Mysql implements IDataBase { private String connurl; private String userName; private String password; public Mysql(String connurl,String userName,String password){ this.connurl = connurl; this.userName = userName; this.password = password; } public Mysql(String serverName,String dbName,String userName,String password){ this.connurl = "jdbc:mysql:"+serverName+"/"+dbName; this.userName = userName; this.password = password; } public String getConnUrl() { // TODO Auto-generated method stub return connurl; } public String getDirver() { // TODO Auto-generated method stub return "com.mysql.jdbc.Driver"; } public String getPassword() { // TODO Auto-generated method stub return password; } public String getUserName() { // TODO Auto-generated method stub return userName; } }
3.数据库连接类
package xidian.xidian.sl.dbconnectpool; import java.sql.Connection; import java.sql.DriverManager; /** * 数据库连接类 * 说明:该方法为单个数据库的连接类,可以脱离连接池来单独使用 * */ public class DBConnector { private IDataBase db; private Connection conn; private boolean free = true; public DBConnector(IDataBase db) { this.db = db; } /** * 连接数据库 * @return 是否连接成功 */ public Connection connect() { try { Class.forName(db.getDirver()).newInstance(); conn = DriverManager.getConnection(db.getConnUrl(), db .getUserName(), db.getPassword()); System.out.println("connect success!"); } catch (Exception e) { System.out.println("connect failure!"); e.printStackTrace(); conn = null; } return conn; } public Connection getConnection(){ return conn; } /** * 判断连接是否在使用 * 注意:在这个地方使用的是包访问权限,这一项是特地为连接池设置的,对于外面应用 的类并不能读到此方法。 * */ boolean isFree() { return free; } /** * 设置连接是否空闲 * @param isFree * */ void setIsFree(boolean isFree) { this.free = isFree; } /** * 关闭数据库 * @return 数据库是否关闭成功 * */ public boolean close() { try { if (conn != null) { conn.close(); } return true; } catch (Exception e) { e.printStackTrace(); System.err.println("close failure!"); return false; } } /** * 释放连接,为连接池的重写提供接口 * @return * */ boolean release(){ throw new RuntimeException("do not use the connection pool,can not release."); } }
4.数据库连接池
package xidian.xidian.sl.dbconnectpool; import java.util.ArrayList; import java.util.List; /** * 连接池 * */ public class DBConnectPool { private int iniSize = 2; //连接池的初始大小 private int addSize = 2; //每次增加的大小 private int maxSize = 4; //最大的大小 private IDataBase db; private List<DBConnector> connections = null; //连接池,初始为空 public DBConnectPool(IDataBase db){ this.db = db; iniPool(); } /** * 初始化连接池 */ public void iniPool(){ connections = new ArrayList<DBConnector>(); connections.addAll(addPool(iniSize)); } /** * 增加连接数 * @param size 要增加的数目 * @return * */ public List<DBConnector> addPool(int size){ List<DBConnector> subList = new ArrayList<DBConnector>(); for(int i=0; i<size; i++){ DBConnector conn = new DBPoolConnector(db); conn.connect(); subList.add(conn); } return subList; } /** * 判断连接数是否超过连接池的最大连接数 * @return 是 否 * */ public boolean isOverRange(){ return connections.size() >= maxSize; } /** * 获得空闲连接 * @return 连接 * */ public DBConnector getConnection(){ //循环,有空闲连接则进行返回 for(DBConnector conn : connections){ if(conn.isFree()){ conn.setIsFree(false); return conn; } } //没有空闲的 if(isOverRange()) { throw new RuntimeException("The connection number is over range."); }else{ int size = addSize; if((connections.size()+size) > maxSize){ size = maxSize - connections.size(); } List<DBConnector> subPool= addPool(size); connections.addAll(subPool); return subPool.get(0); } } /** * 设置连接为空闲状态 * @param conn * */ public void freeConnection(DBConnector conn){ conn.setIsFree(true); } /** * 释放所有的空闲连接 * */ public void releaseAllFree(){ List<DBConnector> subPool = new ArrayList<DBConnector>(); for(DBConnector conn:connections){ if(conn.isFree()){ subPool.add(conn); conn.close(); } } connections.removeAll(subPool); } /** * 释放连接 * @param conn 要释放的连接 * */ public void release(DBConnector conn){ conn.release(); connections.remove(conn); } /** * 释放所有连接 * */ public void release(){ for(DBConnector conn:connections) { conn.release(); } connections.removeAll(connections); } /** * 设置初始化最大连接数 * @param iniSize * */ public void setIniSize(int iniSize) { this.iniSize = iniSize; } /** * 设置每次递增的最大数目 * @param addSize * */ public void setAddSize(int addSize) { this.addSize = addSize; } /** * 设置连接池的最大数目 * @param maxSize * */ public void setMaxSize(int maxSize) { this.maxSize = maxSize; } /** * 连接池内部类,用于管理DBConnector安全性,屏蔽close功能 * */ class DBPoolConnector extends DBConnector{ public DBPoolConnector(IDataBase db) { super(db); } @Override boolean release(){ return super.close(); } @Override public boolean close(){ throw new RuntimeException("Can not close,please use the Connection Pool close this connection."); } } }
希望多多交流,多多关注,共同成就梦想