`
lipsion
  • 浏览: 15389 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

Ibatis2 整合BoneCP

阅读更多
最近开发项目使用Ibatis+Lucene,使用轻量框架实例自己管理,不使用Spring,Ibatis数据源原来使用JNDI,为统一配置加入dbconfig.properties,并使用boneCP,Ibatis2数据源只提供JNDI、SIMPLE、DBCP,无法对BoneCP提供支持,故参考DbcpDataSourceFactory自己创建工厂类,发布博客,以作备份.
dbconfig.properties
###============搜索数据库配置=============##
search.db.url=jdbc:oracle:thin:@(DESCRIPTION =(ADDRESS_LIST =(ADDRESS = (PROTOCOL = TCP)(HOST =*)(PORT = 1521)))(CONNECT_DATA =(SERVER = DEDICATED)(SERVICE_NAME = wcsdb)))
search.db.username=xiu_search
search.db.password=*

##bonecp
##每60秒检查所有连接池中的空闲连接   
search.db.idleConnectionTestPeriod=20
##设置连接空闲时间
search.db.idleMaxAge=20
##设置连接池在每个分区中的最大连接数
search.db.maxConnectionsPerPartition=15
##设置连接池设在每个分区中的最小连接数
search.db.minConnectionsPerPartition=10
##设置分区(设置 2个分区)
search.db.partitionCount=2
##连接池中的连接耗尽的时候 BoneCP一次同时获取的连接数  
search.db.acquireIncrement=5
##每个分区释放链接助理进程的数量,默认值:3,除非你的一个数据库连接的时间内做了很多工作,不然过多的助理进程会影响你的性能  
search.db.releaseHelperThreads=3
search.db.statementsCachedPerConnection=100


<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMapConfig      
    PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"      
    "http://ibatis.apache.org/dtd/sql-map-config-2.dtd">

<sqlMapConfig>
	<properties resource="dbconfig.properties"/>
	
	<settings cacheModelsEnabled="true" enhancementEnabled="true"
		lazyLoadingEnabled="true" maxRequests="10" maxSessions="20"
		maxTransactions="50" useStatementNamespaces="true"
		defaultStatementTimeout="30" statementCachingEnabled="true"
		classInfoCacheEnabled="true" errorTracingEnabled="true" />

     <typeAlias alias="BONECP" type="com.pltfm.sys.util.BoneCPDataSourceFactory"/>
 <transactionManager type="JDBC" commitRequired="false"> 
		<dataSource type="BONECP">
                 <property name="driverClass" value="oracle.jdbc.driver.OracleDriver" />
                 <property name="jdbcUrl" value="${search.db.url}" />
                 <property name="username" value="${search.db.username}" />
                 <property name="password" value="${search.db.password}" />
                 <property name="idleMaxAge" value="${search.db.idleMaxAge}" />
                 <property name="partitionCount" value="${search.db.partitionCount}" />
                 <property name="maxConnectionsPerPartition" value="${search.db.maxConnectionsPerPartition}" />
                 <property name="minConnectionsPerPartition" value="${search.db.minConnectionsPerPartition}" />
                 <property name="driver.encoding" value="UTF8" />
                 <property name="Driver.releaseHelperThreads" value="${search.db.releaseHelperThreads}" />
                 <property name="Driver.statementsCachedPerConnection" value="${search.db.statementsCachedPerConnection}" />
          </dataSource>
	</transactionManager> 
<sqlMap resource="com/pltfm/sys/sqlmap/sys_param_SqlMap.xml" />
</sqlMapConfig>



package com.pltfm.sys.util;

import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.sql.DataSource;

import com.ibatis.common.beans.Probe;
import com.ibatis.common.beans.ProbeFactory;
import com.ibatis.sqlmap.engine.datasource.DataSourceFactory;
import com.jolbox.bonecp.BoneCPDataSource;

/**
 * <h1>支持Ibatis2 BoneCP连接池工厂</h2><br/>
 * <h2>默认提供参数如下:</h2><br/>
 * #driverClass<br/>
 * #jdbcUrl<br/>
 * #username<br/>
 * #password<br/>
 * #每60秒检查所有连接池中的空闲连接   
 * idleConnectionTestPeriod=20<br/>
 * ##设置连接空闲时间<br/>
 * idleMaxAge=20<br/>
 * ##设置连接池在每个分区中的最大连接数<br/>
 * maxConnectionsPerPartition=15<br/>
 * ##设置连接池设在每个分区中的最小连接数<br/>
 * minConnectionsPerPartition=10<br/>
 * ##设置分区(设置 2个分区)<br/>
 * partitionCount=2<br/>
 * ##连接池中的连接耗尽的时候 BoneCP一次同时获取的连接数<br/>  
 * acquireIncrement=5<br/>
 * <span style="color:red">其他自定义参数需以Driver.打头才可注入</span>
 * @see com.ibatis.sqlmap.engine.datasource.DbcpDataSourceFactory
 * @author Lipsion
 *
 */
public class BoneCPDataSourceFactory implements DataSourceFactory {

	private static final Probe PROBE = ProbeFactory.getProbe();
	private static final String ADD_DRIVER_PROPS_PREFIX = "Driver.";
	private static final int ADD_DRIVER_PROPS_PREFIX_LENGTH = ADD_DRIVER_PROPS_PREFIX
			.length();
	private DataSource dataSource;

	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	public void initialize(Map map) {
		try {
			dataSource = legacyBoneCPConfiguration(map);
			if (dataSource == null) {
				dataSource = newBoneCPConfiguration(map);
			}
		} catch (Exception e) {
			throw new RuntimeException(
					"Error initializing BoneCPDataSourceFactory.  Cause: " + e,
					e);
		}
	}
	
	
	public DataSource getDataSource() {
		return dataSource;
	}

	private BoneCPDataSource legacyBoneCPConfiguration(Map<String, String> map) {
		BoneCPDataSource dataSource = null;
		if (map.containsKey("driverClass")) {
			dataSource = new BoneCPDataSource();

			String driver = map.get("driverClass");
			String url = map.get("jdbcUrl");
			String username = map.get("username");
			String password = map.get("password");
			String validationQuery = map.get("connectionTestStatement");
			// 最大连接数
			String maxActive = map.get("maxConnectionsPerPartition");
			// 最大空闲数(最小连接数)
			String maxIdle = map.get("minConnectionsPerPartition");
			String maxWait = map.get("idleMaxAge");
			// 连接池中的连接耗尽的时候 BoneCP一次同时获取的连接数 ,默认为2
			String acquireIncrement = map.get("acquireIncrement");

			if (!notEmpty(url)) {
				throw new RuntimeException(
						"Error initializing configuration. cause: jdbcUrl is empty");
			}
			if (!isNumeric(maxActive)) {
				throw new RuntimeException(
						"Error initializing configuration. cause: maxConnectionsPerPartition is not numeric");
			}

			if (!isNumeric(maxIdle)) {
				throw new RuntimeException(
						"Error initializing configuration. cause: minConnectionsPerPartition is not numeric");
			}

			if (!isNumeric(maxIdle)) {
				throw new RuntimeException(
						"Error initializing configuration. cause: idleMaxAge is not numeric");
			}

			if (!isNumeric(maxWait)) {
				throw new RuntimeException(
						"Error initializing configuration. cause: idleMaxAge is not numeric");
			}
			
			//可选项
			if (notEmpty(acquireIncrement)){
				dataSource.setAcquireIncrement(Integer
						.parseInt(acquireIncrement));
			}

			dataSource.setJdbcUrl(url);
			dataSource.setDriverClass(driver);
			dataSource.setUsername(username);
			dataSource.setPassword(password);
			dataSource.setConnectionTestStatement(validationQuery);
			dataSource.setMaxConnectionsPerPartition(Integer
					.parseInt(maxActive));
			dataSource.setMinConnectionsPerPartition(Integer.parseInt(maxIdle));
			dataSource.setMaxConnectionAge(Long.parseLong(maxWait),
					TimeUnit.SECONDS);

			Iterator<String> props = map.keySet().iterator();
			while (props.hasNext()) {
				String propertyName = (String) props.next();
				if (propertyName.startsWith(ADD_DRIVER_PROPS_PREFIX)) {
					String value = (String) map.get(propertyName);
					// 映射返回对应的类型
					Object convertedValue = convertValue(dataSource,
							propertyName.substring(ADD_DRIVER_PROPS_PREFIX_LENGTH), value);
					PROBE.setObject(dataSource, propertyName.substring(ADD_DRIVER_PROPS_PREFIX_LENGTH), convertedValue);
				}
			}

		}
		return dataSource;
	}

	private BoneCPDataSource newBoneCPConfiguration(Map<String, String> map) {
		BoneCPDataSource dataSource = null;
		Iterator<String> props = map.keySet().iterator();
		while (props.hasNext()) {
			String propertyName = (String) props.next();
			if (propertyName.startsWith(ADD_DRIVER_PROPS_PREFIX)) {
				String value = (String) map.get(propertyName);
				PROBE.setObject(dataSource,
						propertyName.substring(ADD_DRIVER_PROPS_PREFIX_LENGTH),
						value);
			} else if (PROBE.hasWritableProperty(dataSource, propertyName)) {
				String value = (String) map.get(propertyName);
				Object convertedValue = convertValue(dataSource, propertyName,
						value);
				PROBE.setObject(dataSource, propertyName, convertedValue);
			}
		}
		return dataSource;
	}

	private boolean notEmpty(String s) {
		return s != null && s.length() > 0;
	}

	private boolean isNumeric(String str) {
		//如果为空直接返回验证不通过
		if(null==str||"".equals(str)){
			return false;
		}
		Pattern p = Pattern.compile("\\d+");
		Matcher m = p.matcher(str);
		return m.matches();
	}

	@SuppressWarnings("rawtypes")
	private Object convertValue(Object object, String propertyName, String value) {
		Object convertedValue = value;
		Class targetType = PROBE.getPropertyTypeForSetter(object, propertyName);
		if (targetType == Integer.class || targetType == int.class) {
			convertedValue = Integer.valueOf(value);
		} else if (targetType == Long.class || targetType == long.class) {
			convertedValue = Long.valueOf(value);
		} else if (targetType == Boolean.class || targetType == boolean.class) {
			convertedValue = Boolean.valueOf(value);
		}
		return convertedValue;
	}
	
}
分享到:
评论

相关推荐

    水泥袋检测系统源码和数据集:改进yolo11-DCNV4.zip

    水泥袋检测系统源码和数据集:改进yolo11-DCNV4

    德克萨斯扑克分析器Matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    使用Plotly绘制散点图-柱状图-折线图-三维图-饼状图

    使用Plotly绘制散点图_柱状图_折线图_三维图_饼状图

    金银岛谜题Matlab源代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    光敏电阻接线图

    光敏电阻接线图

    MAX30102心率血样传感器原理图.pdf

    MAX30102心率血样传感器原理图

    测试两个多维分布之间的差异(2-d K-S检验,n-d能量检验)Matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    胎儿脑部异常检测系统源码和数据集:改进yolo11-convnextv2.zip

    胎儿脑部异常检测系统源码和数据集:改进yolo11-convnextv2

    MATLAB版本的经典游戏,俄罗斯方块.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    基于Kotlin语言的安卓Camera2拍照录像设计源码

    本项目为基于Kotlin语言的安卓Camera2拍照录像设计源码,总计包含48个文件,涵盖17个XML配置文件、10个WEBP图片文件、5个Kotlin源代码文件、3个Git忽略文件、3个Gradle配置文件、2个Markdown文档、2个属性文件、1个Gradle脚本文件、1个APK安装包以及1个JSON文件。该源码适用于实现安卓设备的拍照和录像功能。

    【C#】设计模式大作业_pgj.zip

    【C#】设计模式大作业_pgj

    基于ruoyi框架的校园后勤Vue前端设计源码

    本项目是一款基于ruoyi框架开发的校园后勤Vue前端设计源码,包含358个文件,涵盖122个Vue组件、93个SVG图标、87个JavaScript脚本、25个PNG图片、10个SCSS样式表、3个批处理脚本、3个JPG图片、2个HTML页面、2个JSON配置文件、2个备份文件。该代码适用于校园后勤管理系统,旨在提升校园后勤服务效率。

    基于Spring Boot框架的校园外卖点餐系统设计源码

    该项目是基于Spring Boot框架的校园外卖点餐系统设计源码,包含162个文件,包括142个Java源文件、16个XML配置文件、2个YML配置文件、1个Git忽略文件和1个XLSX文件。系统采用前后端分离架构,结合Mybatis、Spring Cache、阿里云OSS、Swagger、POI和WebSocket等技术,支持菜品、套餐、订单管理、支付、报表统计及用户催单等功能。系统分为后台管理端和用户端,用户端通过微信小程序实现。我的主要工作包括管理端员工及菜品信息的增删改查功能。

    基于QT框架的OpenCV人脸识别.zip

    基于QT框架的OpenCV人脸识别

    使用赫斯顿模型和条件蒙特卡洛方法计算欧洲看涨期权价格Matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    图像处理新思路:微生物菌落图像分割.zip

    图像处理新思路:微生物菌落图像分割

    基于Python核心的跨语言智能补全插件YouCompleteMe设计源码

    该项目是一款基于Python核心的跨语言智能补全插件YouCompleteMe的设计源码,包含131个文件,涵盖57个Python文件、23个Vim配置文件、6个Markdown文件、5个C/C++源文件、3个YAML配置文件、3个文本文件以及少量其他类型的文件。该插件支持Python、C++、Shell、C等多种编程语言,旨在为开发者提供高效的代码补全功能。

    数据集 + 英国MIDNORCO沉积物岩性数据集

    英国MIDNORCO沉积物岩性数据集 内容: Fyfe, RM (2014) 发布的数据集详细记录了位于英国的MIDNORCO沉积物岩心的岩性特征。此数据集共包含12个数据点,提供了关于该地区地质结构的重要信息。通过访问以下链接可获取完整数据集:"" ()。这些数据对于研究古环境变化、地质年代测定以及了解地球历史具有重要意义。

    数据集 + 威德尔海豹潜水时长数据集

    内容: 本数据集记录了来自Filchner Trough的威德尔海豹(标记为FIL2014_wed_a_m_03)的潜水时长信息,由Bornemann H、Oosthuizen WC、Schröder M等人于2014年发布。该数据集包含了2033个数据点,提供了对单只威德尔海豹潜水行为的详细观察。通过访问以下链接可以获取完整的数据集详情:"" ()。这项研究有助于我们更好地理解威德尔海豹在南极海域中的生活习性与行为模式。

    【光学】基于matlab GUI干涉条纹识别(干涉条纹数 条纹间距)【含Matlab源码 12018期】.zip

    Matlab领域上传的视频是由对应的完整代码运行得来的,完整代码皆可运行,亲测可用,适合小白; 1、从视频里可见完整代码的内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作

Global site tag (gtag.js) - Google Analytics