⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 behdconnect.java

📁 在机器上开一个端口,代理客户端的数据库请求,用在资源有限的终端访问大型数据库上使用,使用jdbc连接orcle, 客户端使用标准的socket即可
💻 JAVA
字号:
package com.behd.db;

import java.io.*;
import java.sql.*;
import java.util.*;
import java.util.Date;
/**
* 管理类behdConnect支持对一个或多个由属性文件定义的数据库连接
* 池的访问.客户程序可以调用getInstance()方法访问本类的唯一实例.
*/
public class behdConnect {
//	私有静态变量, 标识唯一实例
	static private behdConnect instance;	
//	目前活动连接的数目
	static private int clients;
//	连接池所使用的jdbc驱动
	static private Vector drivers = new Vector();	
//	连接池所包含的具体连接池实现,具体的连接池实现对调用者时透明的
	static private Hashtable pools = new Hashtable();
	
	/**
	* 返回唯一实例.如果是第一次调用此方法,则创建实例
	* @return behdConnect 唯一实例
	*/
	static synchronized public behdConnect getInstance() {
		if (instance == null) 
		{
			instance = new behdConnect();
		}
		clients++;
		return instance;
	}

	/**
	* 建构函数私有以防止其它对象创建本类实例
	*/
	private behdConnect() {
		try{
			init();
		}catch(Exception e){
			instance = null;
		}
	}
	
	/**
	 * 类似析构函数,在回收对象的时候,释放资源
	 */
	public void finalize()
	{
		//清空整个连接池
		release();
	}
	
	/**
	 * 读取属性完成初始化
	 * 根据配置文件导入驱动,创建连接池
	 */
	private void init() throws behdException {
		 InputStream is = getClass().getResourceAsStream("db.properties");
		 Properties dbProps = new Properties();
		 try {
		 	dbProps.load(is);
		 }
		 catch (Exception e) {
		 	System.out.println(new Date() + "不能打开配置文件,db.properties\n 请确认文件在正确目录. \n");
		 	return;
		 }
		 if(dbProps.getProperty("useStdPrint").equals("Y")){
		 	behdLog.bLogStdOut = true;
		 }
		 //该类可以管理多个驱动
		 loadDrivers(dbProps);
		 //该类可以管理多个连接池
		 createPools(dbProps);
	}
	
	/**
	 * 装载和注册所有JDBC驱动程序
	 * @param props 属性
	 */
	private void loadDrivers(Properties props) {
	 	String driverClasses = props.getProperty("drivers");
	 	StringTokenizer st = new StringTokenizer(driverClasses);
	 	while (st.hasMoreElements()) {
	 		String driverClassName = st.nextToken().trim();
	 		try {
	 			Driver driver = (Driver)Class.forName(driverClassName).newInstance();
	 			DriverManager.registerDriver(driver);
	 			drivers.addElement(driver);
	 			behdLog.log("连接池管理程序-注册驱动" + driverClassName + "成功!");
	 		}
	 		catch (Exception e) {
	 			behdLog.log("连接池管理程序-注册驱动" + driverClassName + "错误");
	 			e.printStackTrace(System.out);
	 			
	 		}
		}
	}
	
	/**
	 * 根据指定属性创建连接池实例.
	 *
	 * @param props 连接池属性
	 */
	private void createPools(Properties props) {
		System.out.println(new Date() + "createPools");
		Enumeration propNames = props.propertyNames();
		while (propNames.hasMoreElements()) {
			String name = (String) propNames.nextElement();
			if (name.endsWith(".url")) {
				String poolName = name.substring(0, name.lastIndexOf("."));
				String url = props.getProperty(poolName + ".url");
				if (url == null) {
					behdLog.log(new Date() + "没有为连接池" + poolName + "指定URL");
					continue;
				}
				String user = props.getProperty(poolName + ".user");
				String password = props.getProperty(poolName + ".password");
				String maxconn = props.getProperty(poolName + ".maxconn", "0");
				int max;
				try {
					Integer nconn=Integer.valueOf(maxconn);
					max = nconn.intValue();
				}
				catch (NumberFormatException e) {
					behdLog.log(new Date() + "连接池-" + poolName + "-的错误的最大连接数限制: " + maxconn + " 错误!");
					e.printStackTrace(System.out);
					max = 0;
				}
				behdConnectectionPool pool =
				new behdConnectectionPool(poolName, url, user, password, max);
				pools.put(poolName, pool);
				behdLog.log(new Date() + "连接池管理程序-成功创建连接池" + poolName);
	 		}
		}
	}
	
	/**
	* 获得一个可用的(空闲的)连接.如果没有可用连接,且已有连接数小于最大连接数
	* 限制,则创建并返回新连接
	*
	* @param name 在属性文件中定义的连接池名字
	* @return Connection 可用连接或null
	*/
	public Connection getConnection(String name) {
		behdConnectectionPool pool ;
		pool = (behdConnectectionPool) pools.get(name);
		if (pool != null) {
			return pool.getConnection();
		}else{
			behdLog.log("连接池管理程序-监测到对不存在的连接池访问-" + name);
		}
		return null;
	}
	
	
	public Connection getNewDBConnection(String name) {
		behdConnectectionPool pool ;
		pool = (behdConnectectionPool) pools.get(name);
		if (pool != null) {
			return pool.getNewDBConnection();
		}else{
			behdLog.log("连接池管理程序-监测到对不存在的连接池访问-" + name);
		}
		return null;
	}
	
	/**
	* 将连接对象返回给由名字指定的连接池
	*
	* @param name 在属性文件中定义的连接池名字
	* @param con 连接对象
	*/
	public void freeConnection(String name, Connection con) {
		behdConnectectionPool pool;
		pool = (behdConnectectionPool) pools.get(name);
		if( pool == null){
			behdLog.log("连接池" + name + "不存在");
		}else{
			pool.freeConnection(con);
		}
	}
	
	/**
	 * 关闭所有连接,撤销驱动程序的注册
	 */
	public synchronized void release() {
		
		behdLog.log("连接池管理程序开始释放连接池资源");
		
		Enumeration allPools = pools.elements();
		while (allPools.hasMoreElements()) {
			behdConnectectionPool pool = (behdConnectectionPool) allPools.nextElement();
			pool.release();
		}
		
		Enumeration allDrivers = drivers.elements();
		while (allDrivers.hasMoreElements()) {
			Driver driver = (Driver) allDrivers.nextElement();
	 		try {
			 	DriverManager.deregisterDriver(driver);
			 	behdLog.log("连接池管理程序撤销已经注册的JDBC驱动程序:" + driver.getClass().getName());
	 		}
	 		catch (SQLException e) {
	 			behdLog.log("连接池管理程序无法撤销下列JDBC驱动程序的注册: " + driver.getClass().getName());
	 			e.printStackTrace(System.out );
	 		}
	 	}
	}



	static public void main(String[] arg){
		behdConnect behdconn;
		System.out.println("start up:");	
		behdconn = behdConnect.getInstance();
		Connection conn;
		Connection conn1;
		System.out.println("start up:2");
		if(behdconn != null)
		{
			for(int i=0; i < 1; i++)
			{	
				System.out.println("in ");
				conn = behdconn.getConnection("ehdzb");
				//conn = behdconn.getConnection("ehdscm");
				if (conn != null)
				{
					System.out.println("获取连接成功1!");
				}
				conn1 = behdconn.getConnection("ehdzb");
				//conn1 = behdconn.getConnection("ehdscm");
				if (conn1 != null)
				{
					System.out.println("获取连接成功2!");
				}
				behdconn.freeConnection("ehdzb",conn);
				//behdconn.freeConnection("ehdscm",conn);
				System.out.println("释放连接成功1!");
				conn = null;
			}
			
		}
		System.out.println("start up:3");
	} 

	/**
	 * 此内部类定义了一个连接池.它能够根据要求创建新连接,直到预定的最
	 * 大连接数为止.在返回连接给客户程序之前,它能够验证连接的有效性.
	 */
	class behdConnectectionPool {
		//空闲数据库连接	
		private Vector freeConnections = new Vector();
		private int maxConn;		//允许的最大连接数
		private int checkedOut;		//已经分配的连接数
		private String URL;			//数据库连接用url
		private String name;		//连接池名称
		private String password;	//密码
		private String user;		//登陆名
		
		/**
		 * 创建新的连接池
		 * @param name 连接池名字
		 * @param URL 数据库的JDBC URL
		 * @param user 数据库帐号,或 null
		 * @param password 密码,或 null
		 * @param maxConn 此连接池允许建立的最大连接数
		 */
		public behdConnectectionPool(String name, String URL, String user, String password,int maxConn) 
		{
		 	this.name = name;
		 	this.URL = URL;
		 	this.user = user;
		 	this.password = password;
		 	this.maxConn = maxConn;
		}
		
		/**
		 * 创建新的连接,私有函数!
		 */
		private Connection newConnection() 
		{
			Connection con = null;
			try {
				if (user == null) 
				{
					con = DriverManager.getConnection(URL);
			 	}
			 	else 
			 	{
				 	con = DriverManager.getConnection(URL, user, password);
			 	}
				behdLog.log(name,"连接池向数据库取新连接"+con.toString());
			 	if(con.getAutoCommit() == true){
			 		con.setAutoCommit(false);
			 	}
		 	}
		 	catch (SQLException e) 
		 	{
		 		behdLog.log(name,"连接池向数据库取新连接错误: " + URL);
		 		behdLog.log(e);
			 	return null;
		 	}
		 	return con;
		}
		/**
		 * 分配连接:从数据库获得一个可用连接.当数据库重新启动等原因造成连接池中的连接不可用
		 * 从数据库取新的连接.
		 */
		public synchronized Connection getNewDBConnection() 
		{
			Connection con = null;
			con = newConnection();
			checkedOut++;
		 	return con;
		}
		
		/**
		 * 分配连接:从连接池获得一个可用连接.如没有空闲的连接且当前连接数小于最大连接
		 * 数限制,则创建新连接.如原来登记为可用的连接不再有效,则从向量删除之,
		 * 然后递归调用自己以尝试新的可用连接.
		 */
		public synchronized Connection getConnection() 
		{
			Connection con = null;
			if (freeConnections.size() > 0) 
			{
				// 获取向量中第一个可用连接
		 		con = (Connection) freeConnections.firstElement();
		 		if(con == null){
		 			behdLog.log(name,"删除无效null连接,继续取其它连接!");
		 			con = getConnection();
				}
		 		freeConnections.removeElementAt(0);
		 		try {
		 			if (con.isClosed()) 
		 			{
		  				checkedOut--;
		  				behdLog.log(name,"删除无效连接,继续取其它连接!"+con.toString());
		 				// 递归调用自己,尝试再次获取可用连接
		 				con = getConnection();
		 			}
		 		}
		 		catch (SQLException e) {
		 			behdLog.log(name,"删除无效连接错误,继续取其它连接!"+con.toString());
		 			behdLog.log(e);
		 			// 递归调用自己,尝试再次获取可用连接
		 			con = getConnection();
		 		}
		 	}else{
		 		if (maxConn == 0 || checkedOut < maxConn) {
			 		con = newConnection();
			 		checkedOut++;
			 	}else{
			 		//等待
			 	}
		 	}
		 	if (con != null) {
		 		behdLog.log(name,"取连接:"+con.toString());
		 	}
		 	return con;
		}

		/**
		 * 将不再使用的连接返回给连接池
		 *
		 * @param con 客户程序释放的连接
		 */
		public synchronized void freeConnection(Connection con) 
		{
			if(con == null){
				behdLog.log(name,"归还连接 null");
			}else{
				// 将指定连接加入到向量末尾
				freeConnections.addElement(con);
				behdLog.log(name,"归还连接" + con.toString());
			}
			checkedOut--;
			notifyAll();
		}
		
		/**
		 * 关闭本连接池的所有连接
		 */
		public synchronized void release() 
		{
			Enumeration allConnections = freeConnections.elements();
			while (allConnections.hasMoreElements()) 
			{
				Connection con = (Connection) allConnections.nextElement();
				try {
					con.close();
					behdLog.log(name,"关闭一个连接" + con.toString());
		 		}
		 		catch (SQLException e) {
		 			behdLog.log(name,"关闭连接错误" + con.toString());
		 			behdLog.log(e);
		 		}
		 	}
			behdLog.log(name,"关闭连接池中的freeConnections中的所有连接!");
		 	freeConnections.removeAllElements();
		}
		
		/**
		 * 类似析构函数,在回收对象的时候,释放资源
		 */
		public void finalize()
		{
			//清空整个连接池
			behdLog.log(name,"正在释放连接池中的所有连接...");
			release();
		}
	}

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -