AutoSelectNativeJdbcExtractor提供自动选择extractor实例的能力
package com.ejintai.fa.app.integration.jdbc;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Map;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor;
public class AutoSelectNativeJdbcExtractor
implements NativeJdbcExtractor, InitializingBean
{
protected Logger logger = Logger.getLogger(getClass());
private NativeJdbcExtractor defaultExtractor;
protected NativeJdbcExtractor jdbcExtractor;
private Map<String, String> extractorClassMapping;
public Map<String, String> getExtractorClassMapping()
{
return this.extractorClassMapping;
}
public void setExtractorClassMapping(Map<String, String> extractorClassMapping) {
this.extractorClassMapping = extractorClassMapping;
}
public NativeJdbcExtractor getDefaultExtractor() {
return this.defaultExtractor;
}
public void setDefaultExtractor(NativeJdbcExtractor defaultExtractor) {
this.defaultExtractor = defaultExtractor;
}
private NativeJdbcExtractor getJdbcExtractor(Object o) {
if (this.jdbcExtractor == null)
{
String objClass = o.getClass().getName();
NativeJdbcExtractor extractor = null;
if (this.extractorClassMapping != null) {
for (String classPrefix : this.extractorClassMapping.keySet()) {
if (objClass.indexOf(classPrefix) != -1)
{
String className = (String)this.extractorClassMapping.get(classPrefix);
try {
this.logger.info("尝试实例化extractor:" + className);
if (className != null) {
Class clz = getClass().getClassLoader().loadClass(className);
if (clz != null) {
extractor = (InitializingBean)clz.newInstance();
break;
}
}
}
catch (Exception e) {
this.logger.info("尝试实例化extractor:" + className + "时失败; 忽略该异常,继续尝试下一个", e);
}
}
}
}
if (extractor == null) {
this.logger.info("使用默认的extractor:" + this.defaultExtractor);
extractor = this.defaultExtractor;
}
synchronized (this) {
if (this.jdbcExtractor == null) {
this.jdbcExtractor = extractor;
}
}
}
return this.jdbcExtractor;
}
public boolean isNativeConnectionNecessaryForNativeStatements()
{
return true;
}
public boolean isNativeConnectionNecessaryForNativePreparedStatements()
{
return true;
}
public boolean isNativeConnectionNecessaryForNativeCallableStatements()
{
return true;
}
public Connection getNativeConnection(Connection con) throws SQLException
{
return getJdbcExtractor(con).getNativeConnection(con);
}
public Connection getNativeConnectionFromStatement(Statement stmt)
throws SQLException
{
return getJdbcExtractor(stmt).getNativeConnectionFromStatement(stmt);
}
public Statement getNativeStatement(Statement stmt) throws SQLException
{
return getJdbcExtractor(stmt).getNativeStatement(stmt);
}
public PreparedStatement getNativePreparedStatement(PreparedStatement ps)
throws SQLException
{
return getJdbcExtractor(ps).getNativePreparedStatement(ps);
}
public CallableStatement getNativeCallableStatement(CallableStatement cs)
throws SQLException
{
return getJdbcExtractor(cs).getNativeCallableStatement(cs);
}
public ResultSet getNativeResultSet(ResultSet rs)
throws SQLException
{
return getJdbcExtractor(rs).getNativeResultSet(rs);
}
public void afterPropertiesSet() throws Exception
{
if (this.defaultExtractor == null)
throw new IllegalArgumentException("AutoSelectNativeJdbcExtractor的defaultExtractor属性必须指定");
}
}
biz-context.xml中:
<!--
自动根据不同的连接池实现选择对应的nativeJdbcExtractor
目前支持commons-dbcp,tomcat-dbcp,tomcat7-pool,WAS Connection Pool
Need JTFA 2.4.0+
-->
<bean id="nativeJdbcExtractor" class="com.ejintai.fa.app.integration.jdbc.AutoSelectNativeJdbcExtractor" >
<property name="defaultExtractor">
<bean class="org.springframework.jdbc.support.nativejdbc.SimpleNativeJdbcExtractor" />
</property>
<property name="extractorClassMapping">
<map>
<entry key="org.apache.commons.dbcp" value="org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor"/>
<entry key="org.apache.tomcat.dbcp" value="org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor"/>
<entry key="com.ibm" value="org.springframework.jdbc.support.nativejdbc.WebSphereNativeJdbcExtractor"/>
</map>
</property>
</bean>
自动匹配原理和规则 该类进行自动匹配的原理是,在获取到(被连接池”包装过的”)Connection对象后,根据连接的”包装类”的包名前缀来判断当前使用的是哪一种连接池,并根据配置的 包名前缀–Extractor实现类 映射关系获取到要使用的NativeJdbcExtractor实现。
经过测试,我们使用如下匹配关系:
包前缀 | NativeJdbcExtractor实现 |
---|---|
org.apache.commons.dbcp | CommonsDbcpNativeJdbcExtractor |
org.apache.tomcat.dbcp | CommonsDbcpNativeJdbcExtractor |
com.ibm | WebSphereNativeJdbcExtractor |
default(包括tomcat-pool) | SimpleNativeJdbcExtractor |
使用范例
同已有代码的使用方式一样,先获取Spring管理的Connection对象,再从中抽取出原始连接
DemoDAOImpl.java:
@Autowired
private NativeJdbcExtractor nativeJdbcExtractor;
//如果使用[原始连接]进行操作,请使用@Transactional注解(在DAO或者更外层的Service,Action上应用),让Spring容器来管理连接的释放,
@Transactional(rollbackFor=DAOException.class)
@Override
public String nativeJdbcTest() throws DAOException {
//使用native connection 调用package
//获取容器管理的[连接池连接],该连接应当由Spring容器关闭, 你应当在DAO或者更外层的Service,Action上使用@Transactional来开启事务
Connection pooledConn = DataSourceUtils.getConnection(super.getDataSource());
try {
//抽取出(原始连接)
Connection conn = nativeJdbcExtractor.getNativeConnection(pooledConn); //该连接不应当关闭
StructDescriptor sd = new StructDescriptor("WEB_FIN_PRM_TYPE", conn);
STRUCT[] struct = new STRUCT[1];
struct[0]=new STRUCT(sd,conn, getTestValueArray());
ArrayDescriptor ad = ArrayDescriptor.createDescriptor("TYPE_PRM_DATA_ARRAY", conn);
ARRAY array = new ARRAY(ad, conn, struct);
OracleCallableStatement callStatement =
(OracleCallableStatement)conn.prepareCall("{call PKG_FINARP_INTERFACE.PROC_INSERT_DATA_TO_PRM(?)}");
callStatement.setARRAY(1, array);
callStatement.executeUpdate();
} catch (SQLException e) {
throw new DAOException(e);
}
return "ok";
}
下一篇: node.js简单实现注册功能