使用web服务器配置jndi时如何在项目中取出原生的OracleConnection

当我们使用web服务器配置JNDI,而在项目中使用dataSource.getConnection()时取出的链接往往是经过web容器包装后的Connection,如Websphere包装后的连接是com.ibm.ws.rsadapter.jdbc.WSJdbcConnection,但在应用中有时需要使用原生的OracleConnection(包括其子类)来进行特定的操作,比如使用Oracle AQ时就必须要用OracleConnection。本文将简单的介绍如何对取出的连接进行转换获取需要的连接,以及在tomcat下如何配置,让取出的Connection就是OracleConnection家的。

1.对取出的连接进行转换获取需要的连接
当然你可以自己编写代码,不过这件事spring已经帮忙解决了,spring提供的NativeJdbcExtractor可以很出色的完成这个任务,针对不同的web服务器有不同的实现类:
[img]http://dl2.iteye.com/upload/attachment/0100/4151/ac076bf1-71d2-3cf8-9f87-e7713f7ab3ad.jpg[/img]
下面一段简单的代码是依靠NativeJdbcExtractor为Oracle AQ获取原生的OracleConnection

package com.lc.oracle.aq;

import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.sql.DataSource;

import oracle.jdbc.OracleConnection;
import oracle.jms.AQjmsQueueConnectionFactory;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor;


public class OracleAQConnectionFactory implements ConnectionFactory {

protected static final Logger logger = LoggerFactory.getLogger(OracleAQConnectionFactory.class);

private DataSource dataSource;

private NativeJdbcExtractor nativeJdbcExtractor;

public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}

public void setNativeJdbcExtractor(NativeJdbcExtractor nativeJdbcExtractor) {
this.nativeJdbcExtractor = nativeJdbcExtractor;
}

@Override
public javax.jms.Connection createConnection() throws JMSException {
java.sql.Connection con = DataSourceUtils.getConnection(this.dataSource);
java.sql.Connection conToUse = con;
if (!(con instanceof OracleConnection)) {
if (logger.isDebugEnabled()) {
logger.debug("Unwrapping JDBC Connection of type:" + con.getClass().getName());
}
try {
conToUse = (OracleConnection) this.nativeJdbcExtractor.getNativeConnection(con);
if (logger.isDebugEnabled()) {
logger.debug("Using Native JDBC Connection [" + conToUse + "]");
}
} catch (Exception e) {
throw new RuntimeException("Error unwrapping the Oracle Connection: " + e.getMessage(), e);
}
}
return AQjmsQueueConnectionFactory.createQueueConnection(conToUse);
}

@Override
public javax.jms.Connection createConnection(String username, String password) throws JMSException {
throw new UnsupportedOperationException("creating connection with explicit username/password not supported");
}
}

当然如果你的项目中使用了Oracle AQ,完全不需要这么做,你可以使用以下代码:

<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/test" proxy-interface="javax.sql.DataSource" />

<!-- Oracle Advanced Queue Connection Factory -->
<orcl:aq-jms-connection-factory id="connectionFactory" connection-factory-type="QUEUE_CONNECTION"
data-source="dataSource" native-jdbc-extractor="webSphereNativeJdbcExtractor"
use-local-data-source-transaction="true" />

<!-- Jdbc Extractor -->
<bean id="webSphereNativeJdbcExtractor" class="org.springframework.jdbc.support.nativejdbc.WebSphereNativeJdbcExtractor" />

既然是这样,那么我给出上面那段简单代码是什么用意呢?也许你已经发现上面那段代码第34行在获取连接时并没有使用dataSource.getConnection(),而使用的是DataSourceUtils.getConnection(this.dataSource),这么做的目的是为了防止连接泄漏,这篇文章里有很好的讲解[url]http://www.ibm.com/developerworks/cn/java/j-lo-spring-ts3/[/url],我在这里点出来是为了大家更好的学习。

2.在tomcat下如何配置,让取出的Connection就是OracleConnection?
我们一般在tomcat下配置jndi会使用下面的方式:

<Resource name="jdbc/test"
auth="Container"
type="javax.sql.DataSource"
username="dbusername"
password="dbpassword"
driverClassName="oracle.jdbc.driver.OracleDriver"
url="jdbc:oracle:thin:@ip:1521:orcl"
maxActive="100"
maxIdle="10"
maxWait="10000"/>

这样配置在使用时不经转换就会报错:
[img]http://dl2.iteye.com/upload/attachment/0100/4256/7effe0ce-3260-3341-b0c3-5950d06aa08b.jpg[/img]
(图中的oracle.jdbc.internal.OracleConnection extends oracle.jdbc.OracleConnection)

如果要让取出的连接不经转换就是Oracle的Connection,需要把type和driverClassName改成oracle.jdbc.pool.OracleDataSource,factory默认是org.apache.commons.dbcp.BasicDataSourceFactory,改成oracle.jdbc.pool.OracleDataSourceFactory,这时你再测试就会报错:用户名或密码错误,这个问题很奇怪,需要把上面的username改成user,至于为什么,没有找到相关的文档说明。
修改之后的配置如下:

<Resource name="jdbc/test"
auth="Container"
type="oracle.jdbc.pool.OracleDataSource"
factory="oracle.jdbc.pool.OracleDataSourceFactory"
user="dbusername"
password="dbpassword"
driverClassName="oracle.jdbc.pool.OracleDataSource"
url="jdbc:oracle:thin:@ip:1521:orcl"
maxActive="100"
maxIdle="10"
maxWait="10000"/>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值