`

实现在运行期动态创建数据源(连接池)

 
阅读更多

      最近在试用wabacus,遇到一个问题:一个应用需要连接多个数据,除了一个主数据库以外,其他数据库连接参数只能在运行时才能从主数据库取得并进行动态创建数据。  wabacus本身是支持多数据库的,但不支持在运行期动态创建数据源。通过咨询wabacus作者以及研究wabacus的源码,想出了一种实现办法。在这里把实现方法记录一下,方便自己也方便别人。

 

=========================================================

思路:
1、搞清框架中创建数据源的思路;
2、想办法模仿并创建数据源,并把创建好的数据源放入框架数据源集合;

实现:
在作者老大指点下,了解了框架中创建数据源并入数据源集合的入口:
com.wabacus.config.ConfigLoadManager 中 loadDataSources 方法的下面几句:
((AbsDataSource)providerObj).setName(name);                 //
((AbsDataSource)providerObj).loadConfig(eleDataSource);     //根据配置信息创建数据源
mDataSources.put(name,((AbsDataSource)providerObj));        //把数据源放入框架数据源集合
……
Config.getInstance().setMDataSources(mDataSources);

搞明白这个,剩下的事情就不难了,整个实现比预期的要简单很多。作一个工具类来实现新增自定义数据源:
//CustomConfigUtil.java

/** 
* @CopyRright (c)2011: BrokenStone 
* @Project: csbhxt 
* @File: CustomeConfigUtil.java 
* @JDK version used: JDK1.6 @ 
 
* @Author: BrokenStone 
* @Blog: http://sheng.javaeye.com) 
* @Email: wdmsyf@yahoo.com 
* @since: 2012-5-13 
* @Ver: 1.0 
*/
package com.iteye.sheng.wabacus.extend.config; 
 
import java.util.Map; 
 
import org.apache.commons.lang.StringUtils; 
import org.apache.commons.logging.Log; 
import org.apache.commons.logging.LogFactory; 
import org.dom4j.DocumentFactory; 
import org.dom4j.Element; 
 
import com.wabacus.config.Config; 
import com.wabacus.config.database.datasource.AbsDataSource; 
import com.wabacus.config.database.datasource.DriverManagerDataSource; 
import com.wabacus.exception.WabacusConfigLoadingException; 
 
/** 
* wabacus框架配置参数增强工具类 
*/
public class CustomConfigUtil { 
	private static final Log log = LogFactory.getLog(CustomConfigUtil.class); 
	 
	/** 
	* 增加自定义数据源 
	* @param eleDataSource 数据源配置参数的Element 
	*/
	public static void addCustomeDataSource(Element eleDataSource) { 
		Map<String, AbsDataSource> mDataSources = Config.getInstance().getMDataSources(); 
	 
		String name = eleDataSource.attributeValue("name"); 
		if (StringUtils.isEmpty(name)) { 
			throw new WabacusConfigLoadingException("必须配置数据源的name属性"); 
		} 
		name = name.trim(); 
		if (mDataSources.containsKey(name)) { 
			throw new WabacusConfigLoadingException("配置的数据源:" + name + "存在重复"); 
		} 
		String provider = eleDataSource.attributeValue("type"); 
		if (provider == null || provider.trim().equals("")) { 
			provider = DriverManagerDataSource.class.getName(); 
		} 
	 
		Object providerObj = null; 
		try { 
			Class c_provider = Class.forName(provider); 
			providerObj = c_provider.newInstance(); 
		} catch (ClassNotFoundException e1) { 
			throw new WabacusConfigLoadingException("无法加载数据源类:" + provider, e1); 
		} catch (Exception e) { 
			throw new WabacusConfigLoadingException("数据源类:" + provider + "无法实例化", e); 
		} 
		if (!(providerObj instanceof AbsDataSource)) { 
			throw new WabacusConfigLoadingException("配置的数据源类:" + provider + "没有继承超类" + AbsDataSource.class.getName()); 
		} 
		 
		((AbsDataSource) providerObj).setName(name); 
		((AbsDataSource) providerObj).loadConfig(eleDataSource); 
		mDataSources.put(name, ((AbsDataSource) providerObj)); 
	} 
	 
	/** 
	* 增加自定义数据源 
	* @param params 
	*/
	public static void addCustomeDataSource(Map<String, String> params){ 
		DocumentFactory df = new DocumentFactory(); 
		Element newDSElement = df.createElement("datasource"); 
		 
		newDSElement.addAttribute("name", params.get("name")); 
		newDSElement.addAttribute("type", params.get("type")); 
		newDSElement.addAttribute("dbtype", params.get("dbtype")); 
		((newDSElement.addElement("property")).addAttribute("name", "driver")).setText( getParam(params, "driver") ); 
		((newDSElement.addElement("property")).addAttribute("name", "url")).setText( getParam(params, "url") ); 
		((newDSElement.addElement("property")).addAttribute("name", "user")).setText( getParam(params, "user") ); 
		((newDSElement.addElement("property")).addAttribute("name", "password")).setText( getParam(params, "password", "") ); 
		((newDSElement.addElement("property")).addAttribute("name", "max_size")).setText( getParam(params, "max_size", "20") ); 
		((newDSElement.addElement("property")).addAttribute("name", "min_size")).setText( getParam(params, "min_size", "5") ); 
		((newDSElement.addElement("property")).addAttribute("name", "timeout")).setText( getParam(params, "timeout", "100")); 
		((newDSElement.addElement("property")).addAttribute("name", "max_statements")).setText( getParam(params, "max_statements", "100")); 
		((newDSElement.addElement("property")).addAttribute("name", "idle_test_period")).setText( getParam(params, "idle_test_period", "50")); 
		((newDSElement.addElement("property")).addAttribute("name", "acquire_increment")).setText( getParam(params, "acquire_increment", "2")); 
		addCustomeDataSource(newDSElement); 
	} 
	 
	private static String getParam(Map<String, String> params, String name){ 
		return params.get(name); 
	} 
	 
	private static String getParam(Map<String, String> params, String name, String defaultValue){ 
		return StringUtils.isEmpty(params.get(name))? defaultValue : params.get(name); 
	} 
}
 

 

使用例子如下:

private void addCustomeDataSourceTest(){ 
	Map<String, String> dsParamMap = new HashMap<String, String>(); 
	dsParamMap.put("name", "MyCustomDS1"); 
	dsParamMap.put("type", "com.wabacus.config.database.datasource.C3P0DataSource"); 
	dsParamMap.put("dbtype", "com.wabacus.config.database.type.MySql"); 
	dsParamMap.put("driver", "com.mysql.jdbc.Driver"); 
	dsParamMap.put("url", "jdbc:mysql://localhost:3306/phonegap?useUnicode=true&characterEncoding=UTF-8"); 
	dsParamMap.put("user", "root"); 
	dsParamMap.put("password", ""); 
	dsParamMap.put("max_size", "20"); 
	dsParamMap.put("min_size", "5"); 
	dsParamMap.put("timeout", "100"); 
	dsParamMap.put("max_statements", "100"); 
	dsParamMap.put("idle_test_period", "50"); 
	dsParamMap.put("acquire_increment", "2"); 
	CustomConfigUtil.addCustomeDataSource( dsParamMap ); 
 
	AbsDataSource ds = Config.getInstance().getDataSource("MyCustomDS1"); 
	Connection conn = ds.getConnection(); 
	Statement stmt = null; 
	ResultSet rs = null; 
	try{ 
		stmt = conn.createStatement(); 
		boolean isSucc = stmt.execute("SELECT * FROM employee"); 
		if(isSucc){ 
			rs = stmt.getResultSet(); 
			StringBuffer sb = new StringBuffer(""); 
			while(rs.next()){ 
				sb.append("id = ").append(rs.getInt("id")).append(", ") 
				.append("firstName = ").append(rs.getString("firstName")).append(", ") 
				.append("lastName = ").append(rs.getString("lastName")).append(", ") 
				.append("managerId = ").append(rs.getString("managerId")).append(", ") 
				.append("title = ").append(rs.getString("title")).append(", ") 
				.append("department = ").append(rs.getString("department")).append(", ") 
				.append("officePhone = ").append(rs.getString("officePhone")).append(", ") 
				.append("cellPhone = ").append(rs.getString("cellPhone")).append(", ") 
				.append("email = ").append(rs.getString("email")).append(", ") 
				.append("city = ").append(rs.getString("city")).append(", ") 
				.append("picture = ").append(rs.getString("picture")).append("\r\n "); 
			} 
			log.debug(sb.toString()); 
			System.out.println(sb.toString()); 
		}else{ 
			log.error("执行SQL语句失败。"); 
		}
	}catch(SQLException ex){ 
		log.error(ex); 
	}finally{ 
		try{ 
			if(rs!=null) rs.close(); 
			rs = null; 
		}catch(SQLException ex){ 
			log.warn(ex); 
		} 
	 
		try{ 
			if(stmt!=null) stmt.close(); 
			stmt = null; 
		}catch(SQLException ex){ 
			log.warn(ex); 
		} 
	 
		try{ 
			if(conn!=null) conn.close(); 
			conn = null; 
		}catch(SQLException ex){ 
			log.warn(ex); 
		}       
	} 
}
 

再次感谢作者提供如此优秀的开发框架并给予无私指导。
分享到:
评论

相关推荐

    Visual C++实践与提高-COM和COM+篇『PDF』

    7.4.4 创建数据源 7.4.5 编写客户程序 7.4.6 三层软件应用模型 小结 第8章 OLE文档与ActiveX文档 8.1 OLE文档基础知识 8.1.1 OLE文档服务器与包容器 8.1.2 OLE服务体系结构 8.1.3 链接与嵌入技术 8.1.4 现场激活...

    ASP3《高级编程》(第一部分)

    10.2.4 数据源对象 301 10.2.5 数据绑定 308 10.2.6 更新数据 316 10.3 在服务器和客户之间传输数据 319 10.3.1 基于服务器的组件 319 10.3.2 DataSpace对象 320 10.3.3 使用服务器端组件的优点 322 10.3.4 ...

    ASP3《高级编程》(第二部分)

    10.2.4 数据源对象 301 10.2.5 数据绑定 308 10.2.6 更新数据 316 10.3 在服务器和客户之间传输数据 319 10.3.1 基于服务器的组件 319 10.3.2 DataSpace对象 320 10.3.3 使用服务器端组件的优点 322 10.3.4 ...

Global site tag (gtag.js) - Google Analytics