jdbc数据源
数据源设计思想和数据库连接池设计思想基本相似。大家知道在操作数据库程序时,创建连接所占用时间最多,为了提高程序的效率,便出现了数据库连接池技术。
数据库连接池实现原理:在系统启动时便创建一定数量连接,将它们放在线程安全的集合中(这便称为数据库连接池),当某段程序要连接数据库时,不必再去创建连接而直接去从池中去取,这样也就减少了创建连接时间。在关闭连接时,也不是真正关闭而是将其重新放回池中。从而提高系统效能。
一下说我最近写的一个数据源类,仅供大家参考:
package dataSource; import java.io.File; import java.io.InputStream; import java.io.PrintWriter; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.DriverManager; import java.sql.SQLException; import java.util.Enumeration; import java.util.Properties; import java.util.Vector; public class DataSource implements javax.sql.DataSource{ /**驱动*/ private String driver; /**url*/ private String url; /**用户名*/ private String user; /**密码*/ private String password; /**初始化连接数*/ private int initCount; /**连接池中最大连接数*/ private int maxCount; /**当前使用连接数*/ private int currentCount=0; /**等待连接最长时间*/ private int wait=3000; /**输出日志流*/ private PrintWriter out; /**连接池*/ private Vector<ConnectionPool> connections; public DataSource(){ init(); initConnections(); } /** * 初始化 */ private void init(){ Properties prop=new Properties(); try { InputStream input=DataSource.class.getClassLoader().getResourceAsStream("dataSource.properties"); prop.load(input); driver=prop.getProperty("driver"); Class.forName(driver);//加载驱动 url=prop.getProperty("url"); user=prop.getProperty("user"); password=prop.getProperty("password"); String itCount=prop.getProperty("initCount"); initCount=itCount==null?1:Integer.parseInt(itCount); String mCount=prop.getProperty("maxCount"); maxCount=mCount==null?1:Integer.parseInt(mCount); connections=new Vector<ConnectionPool>(); out=new PrintWriter(new File("c:/datasouce.log"),"UTF-8"); } catch (Exception e) { e.printStackTrace(); writerLog(e.getMessage()); throw new RuntimeException("装载配置文件错误"); } } /** * 初始化连接池中数据库连接个数 * */ private void initConnections(){ for(int i=0;i<initCount;i++){ try { Connection conn=createConnection(); if(i==0){ DatabaseMetaData metaData=conn.getMetaData(); int dataCount=metaData.getMaxConnections(); writerLog("数据库最大连接数为:"+dataCount); if(dataCount>0&&maxCount>dataCount){ maxCount=dataCount; } } ConnectionPool pool=new ConnectionPool(conn); connections.addElement(pool); } catch (SQLException e) { e.printStackTrace(); writerLog(e.getMessage()); throw new RuntimeException("初始化连接池错误"); } } } /** * 创建连接对象 * @return 创建好的连接对象 * @throws SQLException */ private Connection createConnection() throws SQLException{ currentCount++; writerLog("当前正在使用连接数:"+currentCount); return DriverManager.getConnection(url,user,password); } /** * 当数据源中原有连接已用完时,就创建一个新的数据库连接对象到连接池中 * 且这个连接需要时才被创建,一旦创建就被使用 * @return * @throws SQLException */ private ConnectionPool createConnPool() throws SQLException{ Connection conn=createConnection(); ConnectionPool pool=new ConnectionPool(conn); pool.setBusy(true); writerLog("添加一个新的数据库连接对象到连接池中"); return pool; } /** * 从连接池中得到连接对象 */ public synchronized Connection getConnection() throws SQLException { if(connections==null){ writerLog("连接池已不存在"); return null; } Connection conn=findFreeConnection(); if(conn==null){ if(currentCount<=maxCount){ ConnectionPool conn1=createConnPool(); return conn1.getConn(); }else{ try { writerLog("正在等待数据库连接 ...."); Thread.sleep(wait); return findFreeConnection(); } catch (InterruptedException e) { writerLog(e.getMessage()); e.printStackTrace(); } } } return conn; } /** * 查找当前连接池中还有没有空闲连接 * @return Connection */ private Connection findFreeConnection(){ Connection conn=null; if(connections.size()>0){ Enumeration enu=connections.elements(); while(enu.hasMoreElements()){ ConnectionPool pool=(ConnectionPool)enu.nextElement(); if(!(pool.isBusy())){ conn=pool.getConn(); pool.setBusy(true); writerLog("找到一个空闲连接"); return conn; } } } return conn; } /** * 关闭连接对象(实际上并不是真正的关闭,而是将其状态置为空闲) * @param conn 要关闭连接对象 */ public synchronized void closeConnection(Connection conn){ currentCount--; if(connections.size()==0||connections==null){ writerLog("连接池已不存在"); return; } Enumeration enu=connections.elements(); while(enu.hasMoreElements()){ ConnectionPool pool=(ConnectionPool)enu.nextElement(); if(pool.getConn()==conn){ pool.setBusy(false); writerLog("关闭了当前连接"); break; } } out.close(); } /** * 单独创建一个连接,不从连接池中去取 */ public synchronized Connection getConnection(String username, String password)throws SQLException { writerLog("创建一个独立于连接池的连接对象"); return DriverManager.getConnection(url,username,password); } /** * 获得日志输出流 */ public PrintWriter getLogWriter() throws SQLException { return out; } /** * 设置日志输出流 */ public void setLogWriter(PrintWriter out) throws SQLException { this.out=out; } /** * 如果当前没有可用连接,设置等待时间 毫秒数 */ public void setLoginTimeout(int seconds) throws SQLException { this.wait=seconds; } /** * 或得系统等待连接时间 */ public int getLoginTimeout() throws SQLException { return wait; } private void writerLog(String errMessage){ out.append("#=========================================#\n"); out.append(errMessage+"\n"); out.append("#=========================================#\n"); } /** * 包装到连接池的连接对象 * @author newapps */ class ConnectionPool{ /**当前数据库创建连接*/ Connection conn; /**当前连接是否处于工作状态*/ boolean busy=false; /**构造函数*/ ConnectionPool(Connection conn){ this.conn=conn; } void setBusy(boolean busy){ this.busy=busy; } boolean isBusy(){ return busy; } void setConn(Connection conn){ this.conn=conn; } Connection getConn(){ return conn; } } }
配置文件(dateSource.properties)
#=================================================================================== #各种常用数据库驱动名称 #============mysql Driver==================== #com.mysql.jdbc.Driver #============oracle Driver=================== #oracle.jdbc.driver.OracleDriver #============pointbase Driver================ #com.pointbase.jdbc.jdbcUniversalDriver #============SQL Server Driver=============== #com.microsoft.jdbc.sqlserver.SQLServerDriver #============DB2 Driver====================== #com.ibm.db2.jdbc.app.DB2Driver #=================================================================================== #数据库连接url格式为:"jdbc:子协议:子协议名称//主机名:端口号/数据库名?属性名=属性值&属性名=属性值" #dbUser和dbPassword也可以通过:属性名=属性值方式传入。 #设置数据库的编码格式:useUnicode=true&characterEncoding=GBK #============mysql url============================================================== #jdbc:mysql://<machine_name><:port>/dbname #端口号:默认是 3306 #============oracle url============================================================= #jdbc:oracle:thin:@<machine_name><:port>:dbname #端口号:默认是 1521 #============pointbase url========================================================== #jdbc:pointbase:server://<machine_name><:port>/dbname #端口号:默认是 9092 #============SQL Server url========================================================= #jdbc:microsoft:sqlserver://<machine_name><:port>;DatabaseName=<dbname> #端口号:默认是 1433 #============DB2 url================================================================ #jdbc:db2://<machine_name><:port>/dbname #端口号:默认是 5000 #=================================================================================== #数据库驱动 driver=com.mysql.jdbc.Driver #数据库URL url=jdbc:mysql://127.0.0.1:3306/ajax #连接数据库用户 user=root #连接数据库密码 password=123 #初始化连接数 initCount=1 #连接池中最大连接数 maxCount=50
相关推荐
点滴技术生活 2020-07-19
Laxcus大数据技术 2020-06-11
PengQ 2020-06-06
tlsmile 2020-06-03
wintershii 2020-08-17
LeoHan 2020-06-13
thunderstorm 2020-06-06
Zhangdragonfly 2020-06-05
Kele0 2020-05-30
鲁氏汤包王 2020-04-18
favouriter 2020-04-18
yongyoumengxiang 2020-03-26
heniancheng 2020-03-25
nan00zzu 2020-02-23
步行者 2020-02-20
Java学习 2020-02-17
nan00zzu 2020-02-11
wintershii 2020-02-10