kevin_wanwei 发表于 2013-1-25 22:07:48

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#数据库URLurl=jdbc:mysql://127.0.0.1:3306/ajax#连接数据库用户user=root#连接数据库密码password=123#初始化连接数initCount=1#连接池中最大连接数maxCount=50 
页: [1]
查看完整版本: jdbc数据源