在前面的博客里面提到了 jdbc的驱动注册与连接 但是那个jdbc太旧了 所以自己用jad把ojdbc6.jar进行了反编译 又梳理了一下驱动注册和连接过程 故此记录学习的脚步
在梳理驱动注册的过程前 先来看看jdbc3的保存点和jdbc4的操纵xml 还有一个是transient关键字的测试
package com.undergrowth.jdbc.learn;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.sql.SQLXML;
import java.sql.Savepoint;
import java.sql.Statement;
import oracle.jdbc.pool.OracleDataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 测试jdbc3.0的新特性 jdbc3.0需要jdk1.4及以上才能支持
* 保存点 、 获取自动产生键、
* 结果集的保持性 HOLD_CURSORS_OVER_COMMIT 这位oracle的jdbc的默认设置
*
* jdbc4的 xmltype rowid
* @author Administrator
*
*/
public class Jdbc34Test {
/**
* 日志常量
*/
private static final Logger LOGGER = LoggerFactory
.getLogger(BasicConnectOracle.class);
// 使用thin进行数据库的连接
private StringBuffer connectUrl = new StringBuffer(
"jdbc:oracle:thin:u1/u1@//localhost:1521/orcl");
// 连接的数据源
private OracleDataSource dataSource = null;
private Connection conn = null;
private PreparedStatement pstmt = null;
private Statement stmt = null;
private CallableStatement cs = null;
private ResultSet rset = null;
private Savepoint insertSP = null;
/**
* 初始化数据源
*/
public Jdbc34Test() {
try {
dataSource = new OracleDataSource();
dataSource.setURL(connectUrl.toString());
LOGGER.info("构建OracleDataSource成功!!");
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
LOGGER.error(e.getMessage());
}
}
public OracleDataSource getDataSource() {
return dataSource;
}
public Connection getConn() {
return conn;
}
public PreparedStatement getPstmt() {
return pstmt;
}
public Statement getStmt() {
return stmt;
}
public CallableStatement getCs() {
return cs;
}
public ResultSet getRset() {
return rset;
}
public Savepoint getInsertSP() {
return insertSP;
}
/**
* 测试保存点 CREATE TABLE TEST_TABLE ( ID INTEGER, NAME VARCHAR2(20) )
*/
public void testSavePoint() {
try {
getConnByDatasource();
//设置手动提交
getConn().setAutoCommit(false);
//插入数据1
StringBuffer insertSql =new StringBuffer("insert into TEST_TABLE select 100,'100_under' from dual");
getPstmtBySql(insertSql.toString());
getPstmt().executeUpdate();
//这里坑了半个小时 因为pstmt不置为空的话 下面的pstmt还是使用上面的对象 那么下面的代码 永远都是错的 嘎嘎 1个小时 才搞清楚 还以为是下面写的有问题 哎
pstmt=null;
//建立保存点
insertSP = getConn().setSavepoint("ins");
insertSql= new StringBuffer(
"insert into TEST_TABLE(ID,NAME) values(200,?)");
//构建PreparedStatement
//If key columns are not explicitly indicated, then Oracle JDBC drivers cannot identify which columns need to be retrieved.
getPstmtBySql(insertSql.toString(),new String[]{"NAME"});
getPstmt().setString(1, "200_under");
getPstmt().executeUpdate();
//获取插入的自动产生的键
rset=getPstmt().getGeneratedKeys();
while(getRset().next())
{
LOGGER.info("插入数据 获取自动产生键为:"+rset.getObject(1));
}
// 若提交后 保存点 自动释放 所以无需手工调用 releaseSavepoint()
getConn().commit();
} catch (SQLException e) {
// TODO: handle exception
try {
//判断是否需要 回滚全部操作
if(getInsertSP()==null) getConn().rollback();
else {
getConn().rollback(insertSP);
getConn().commit();
}
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
e.printStackTrace();
LOGGER.error(e1.getMessage()+"\n"+e.getMessage());
}
e.printStackTrace();
LOGGER.error(e.getMessage());
} finally {
closeResources();
}
}
/**
* 测试jdbc4.0的xmltype
* -- Create table
create table TEST_TABLE
(
id INTEGER,
name VARCHAR2(20),
content XMLTYPE
)
*/
public void testXmlType(){
try {
String xmlString="<?xml version='1.0' ?>\n <student>\n <id>1<id>\n <name>张三</name>\n </student>";
getConnByDatasource();
String insertSql="insert into TEST_TABLE values(?,?,?)";
getPstmtBySql(insertSql);
getPstmt().setInt(1, 1000);
getPstmt().setString(2, "测试xml类型");
//构建sqlxml对象
SQLXML sqlxml=getConn().createSQLXML();
//设定值
sqlxml.setString(xmlString);
getPstmt().setSQLXML(3, sqlxml);
int result=getPstmt().executeUpdate();
//释放资源
sqlxml.free();
LOGGER.info("成功插入"+result+"条记录");
pstmt=null;
getPstmtBySql("select * from TEST_TABLE");
rset=getPstmt().executeQuery();
while(getRset().next()){
LOGGER.info("查询的结果为:\t"+getRset().getInt(1)+"\t"+getRset().getString(2)+"\t"+getRset().getSQLXML(3));
}
} catch (SQLFeatureNotSupportedException e) {
// TODO: handle exception
e.printStackTrace();
LOGGER.error("数据特性不支持"+e.getMessage());
}catch (SQLException e) {
// TODO: handle exception
e.printStackTrace();
LOGGER.error(e.getMessage());
}finally{
closeResources();
}
}
/**
* 获取数据库信息
*/
public void testDataMeta(){
try {
getConnByDatasource();
DatabaseMetaData metaData=getConn().getMetaData();
LOGGER.info("数据库为:"+metaData.getDatabaseProductName().toString()+" "+metaData.getDatabaseMajorVersion()+"."+metaData.getDatabaseMinorVersion()+"\n"+metaData.getDatabaseProductVersion());
//获得所有的数据库支持的数据类型
rset=metaData.getTypeInfo();
while(getRset().next()){
LOGGER.info(metaData.getDatabaseProductName()+"支持的数据类型为:"+getRset().getString(1)+"\t驱动版本为:"+metaData.getDriverName()+" "+metaData.getDriverVersion());
}
} catch (SQLException e) {
// TODO: handle exception
e.printStackTrace();
LOGGER.error(e.getMessage());
}finally{
closeResources();
}
}
/**
* 获取Connection对象
*
* @throws SQLException
*/
private void getConnByDatasource() throws SQLException {
if (getConn() == null)
conn = dataSource.getConnection();
}
/**
* 通过语句构建 CallableStatement
*
* @param callSql
* @throws SQLException
*/
private void getCsBySql(String callSql) throws SQLException {
// TODO Auto-generated method stub
if (getCs() == null)
cs = getConn().prepareCall(callSql);
}
/**
* 通过sql 构建PreparedStatement
*
* @param sql
* @throws SQLException
*/
private void getPstmtBySql(String sql) throws SQLException {
if (getPstmt() == null)
pstmt = getConn().prepareStatement(sql);
}
/**
* 根据sql和列名 生成PreparedStatement
*
* @param string
* @param strings
*/
private void getPstmtBySql(String sql, String[] columnsName) {
// TODO Auto-generated method stub
try {
if (getPstmt() == null)
pstmt = getConn().prepareStatement(sql, columnsName);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 关闭资源
*/
private void closeResources() {
// TODO Auto-generated method stub
try {
// 关闭rset和stmt 后 oracle中对应的游标才会关闭
if (getRset() != null)
getRset().close();
if (getStmt() != null)
getStmt().close();
if (getPstmt() != null)
getPstmt().close();
if (getCs() != null)
getCs().close();
if (getConn() != null)
getConn().close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
transient关键字
package com.undergrowth.jdbc.learn;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 用于测试transient关键字的使用
* 使用 transient关键字进行修饰的变量 不会进行序列化
* volatile 表示每次读取值都需重新读取 有改变则需立即写入
* @author Administrator
*
*/
public class TransientTest implements Serializable{
private static Logger logger=LoggerFactory.getLogger(TransientTest.class);
private String username;
private transient String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public TransientTest(String username, String password) {
super();
this.username = username;
this.password = password;
}
public TransientTest() {
super();
}
@Override
public String toString() {
String pwdString=null;
if(getPassword()==null) pwdString="密码没有设定";
else pwdString=getPassword();
return "TransientTest [username=" + username + ", password=" + pwdString
+ "]";
}
/**
* 将对象写到文件中
*/
public void writeTest(){
TransientTest tt=new TransientTest("qq","qq");
logger.info(tt.toString());
try {
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("TransientTest.txt"));
oos.writeObject(tt);
oos.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void readTest(){
TransientTest tt=null;
try {
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("TransientTest.txt"));
tt=(TransientTest) ois.readObject();
logger.info(tt.toString());
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
测试
package com.undergrowth;
import org.junit.Test;
import com.undergrowth.jdbc.learn.Jdbc34Test;
import com.undergrowth.jdbc.learn.TransientTest;
public class Jdbc3TestJunit {
static Jdbc34Test jdbc3Test=null;
static{
jdbc3Test=new Jdbc34Test();
}
@Test
public void testSavePoint(){
jdbc3Test.testSavePoint();
}
@Test
public void testXmlType(){
jdbc3Test.testXmlType();
//PhysicalConnection
/**
* T4CDriverExtension 拥有 T4CConnection 继承 PhysicalConnection(拥有logon()方法中connect(database) net = new NSProtocol();
* net.connect(s, properties);)
*/
}
@Test
public void testDataMeta(){
jdbc3Test.testDataMeta();
}
/**
* 测试transient关键字
*/
@Test
public void testTransientTest(){
TransientTest tt=new TransientTest();
tt.writeTest();
tt.readTest();
}
}
附
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.undergrowth</groupId>
<artifactId>jdbc</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>jdbc</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.1</version>
<scope>test</scope>
</dependency>
<!-- 添加oracle jdbc的依赖 -->
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.7</version>
</dependency>
</dependencies>
</project>
2、好的 上面即使学习的一些笔记 心得 还是来看ojdbc6的驱动注册与连接是怎么一回事吧
这里就直接从 oracle.jdbc.driver.OracleDriver的这里开始了 前面的方式 与之前写的 是一样的 就不写了
在OracleDriver的类里 有一块静态块 用于注册驱动 部分代码
static
{
defaultDriver = null;
try
{
if(defaultDriver == null)
{
defaultDriver = new oracle.jdbc.OracleDriver();
DriverManager.registerDriver(defaultDriver);
}
AccessController.doPrivileged(new PrivilegedAction() {
public Object run()
{
OracleDriver.registerMBeans();
return null;
}
}
首先开始的是 connect方法
public Connection connect(String s, Properties properties)
throws SQLException
{
if(s.regionMatches(0, "jdbc:default:connection", 0, 23))
{
String s1 = "jdbc:oracle:kprb";
int j = s.length();
if(j > 23)
s = s1.concat(s.substring(23, s.length()));
else
s = s1.concat(":");
s1 = null;
}
int i = oracleDriverExtensionTypeFromURL(s);
if(i == -2)
return null;
if(i == -3)
{
SQLException sqlexception = DatabaseError.createSqlException(getConnectionDuringExceptionHandling(), 67);
sqlexception.fillInStackTrace();
throw sqlexception;
}
OracleDriverExtension oracledriverextension = null;
oracledriverextension = driverExtensions[i];
if(oracledriverextension == null)
try
{
synchronized(this)
{
if(oracledriverextension == null)
{
oracledriverextension = (OracleDriverExtension)Class.forName(driverExtensionClassNames[i]).newInstance();
driverExtensions[i] = oracledriverextension;
} else
{
oracledriverextension = driverExtensions[i];
}
}
}
catch(Exception exception)
{
SQLException sqlexception1 = DatabaseError.createSqlException(getConnectionDuringExceptionHandling(), exception);
sqlexception1.fillInStackTrace();
throw sqlexception1;
}
if(properties == null)
properties = new Properties();
Enumeration enumeration = DriverManager.getDrivers();
Object obj;
do
{
if(!enumeration.hasMoreElements())
break;
obj = (Driver)(Driver)enumeration.nextElement();
} while(!(obj instanceof OracleDriver));
do
{
if(!enumeration.hasMoreElements())
break;
obj = (Driver)(Driver)enumeration.nextElement();
if(obj instanceof OracleDriver)
DriverManager.deregisterDriver(((Driver) (obj)));
} while(true);
obj = (PhysicalConnection)oracledriverextension.getConnection(s, properties);
obj.protocolId = i;
return ((Connection) (obj));
}
当然里面的重点是 这一句
obj = (PhysicalConnection)oracledriverextension.getConnection(s, properties);
你会发现 PhysicalConnection 是一个抽象类 那么此时调用的getConnection必是它的继承类
那就是 oracledriverextension 这个变量了 来源于这
OracleDriverExtension oracledriverextension = null;
oracledriverextension = driverExtensions[i];
if(oracledriverextension == null)
try
{
synchronized(this)
{
if(oracledriverextension == null)
{
oracledriverextension = (OracleDriverExtension)Class.forName(driverExtensionClassNames[i]).newInstance();
driverExtensions[i] = oracledriverextension;
} else
{
oracledriverextension = driverExtensions[i];
}
}
}
先从driverExtensions数组中找 如果为空的话 则创建一个对象 那么看看driverExtensions是什么
public OracleDriver()
{
driverExtensions = new OracleDriverExtension[4];
}
他是一个数组而已 那么上面的 oracledriverextension 的值的话 就取决于 driverExtensionClassNames[i]了 那么它是什么呢
private static final String driverExtensionClassNames[] = {
"oracle.jdbc.driver.T4CDriverExtension", "oracle.jdbc.driver.T4CDriverExtension", "oracle.jdbc.driver.T2CDriverExtension", "oracle.jdbc.driver.T2SDriverExtension"
};
哦 一个字符串数组 所以 要想确定oracledriverextension 到底是上面数组中的哪一个类的对象的话 取决于 i的值 那找找吧 来源于
int i = oracleDriverExtensionTypeFromURL(s);
static final int oracleDriverExtensionTypeFromURL(String s)
{
int i = s.indexOf(':');
if(i == -1)
return -2;
if(!s.regionMatches(true, 0, "jdbc", 0, i))
return -2;
i++;
int j = s.indexOf(':', i);
if(j == -1)
return -2;
if(!s.regionMatches(true, i, "oracle", 0, j - i))
return -2;
j++;
int k = s.indexOf(':', j);
String s1 = null;
if(k == -1)
return -3;
s1 = s.substring(j, k);
if(s1.equals("thin"))
return 0;
return !s1.equals("oci8") && !s1.equals("oci") ? -3 : 2;
}
如果我们的URL 类似于 jdbc:oracle:thin:@//localhost:1521:orcl 的话 那么 上面函数返回0 那么
driverExtensionClassNames[i]="oracle.jdbc.driver.T4CDriverExtension"
那么
obj = (PhysicalConnection)oracledriverextension.getConnection(s, properties);
即是调用的 T4CDriverExtension对象的getConnection 进行连接 T4CDriverExtension的构造函数
Connection getConnection(String s, Properties properties)
throws SQLException
{
return new T4CConnection(s, properties, this);
}
T4CConnection的构造函数如下
T4CConnection(String s, Properties properties, OracleDriverExtension oracledriverextension)
throws SQLException
{
super(s, properties, oracledriverextension);
LOGON_MODE = 0L;
xsListeners = new NTFEventListener[0];
EMPTY_BYTE = new byte[0];
pipeState = -1;
sentCancel = false;
cancelInProgressFlag = false;
statementCancel = true;
currentTTCSeqNumber = 0;
cursorToClose = new int[4];
cursorToCloseOffset = 0;
queryToClose = new int[10];
queryToCloseOffset = 0;
lusFunctionId2 = new int[10];
lusSessionId2 = new byte[10][];
lusInKeyVal2 = new KeywordValueLong[10][];
lusInFlags2 = new int[10];
lusOffset2 = 0;
minVcsBindSize = 0;
streamChunkSize = 255;
namespaces = new Hashtable(5);
currentSchema = null;
}
哦 其中有一句
super(s, properties, oracledriverextension);
调用父类构造函数 那么父类是谁呢 哦 PhysicalConnection 看看它的构造函数吧
PhysicalConnection(String s, Properties properties, OracleDriverExtension oracledriverextension)
throws SQLException
{
outScn = 0L;
charOutput = new char[1][];
byteOutput = new byte[1][];
shortOutput = new short[1][];
sessionProperties = null;
ociConnectionPoolMinLimit = 0;
ociConnectionPoolMaxLimit = 0;
ociConnectionPoolIncrement = 0;
ociConnectionPoolTimeout = 0;
ociConnectionPoolNoWait = false;
ociConnectionPoolTransactionDistributed = false;
ociConnectionPoolLogonMode = null;
ociConnectionPoolIsPooling = false;
ociConnectionPoolObject = null;
ociConnectionPoolConnID = null;
ociConnectionPoolProxyType = null;
ociConnectionPoolProxyNumRoles = Integer.valueOf(0);
ociConnectionPoolProxyRoles = null;
ociConnectionPoolProxyUserName = null;
ociConnectionPoolProxyPassword = null;
ociConnectionPoolProxyDistinguishedName = null;
ociConnectionPoolProxyCertificate = null;
protocolId = -3;
txnMode = 0;
clientIdSet = false;
clientId = null;
descriptorCacheStack = new Hashtable[2];
dci = 0;
databaseMetaData = null;
isProxy = false;
sqlObj = null;
sqlWarning = null;
readOnly = false;
statementCache = null;
clearStatementMetaData = false;
closeCallback = null;
privateData = null;
savepointStatement = null;
isUsable = true;
defaultTimeZone = null;
endToEndMaxLength = new int[4];
endToEndAnyChanged = false;
endToEndHasChanged = new boolean[4];
endToEndECIDSequenceNumber = -32768;
endToEndValues = null;
wrapper = null;
instanceName = null;
databaseProductVersion = "";
versionNumber = -1;
plsqlCompilerWarnings = false;
sessionTimeZone = null;
databaseTimeZone = null;
dbTzCalendar = null;
timeZoneVersionNumber = -1;
timeZoneTab = null;
cancelInProgressLockForThin = new Object();
readConnectionProperties(s, properties);
driverExtension = oracledriverextension;
initialize(null, null, null);
logicalConnectionAttached = null;
try
{
needLine();
logon();
setAutoCommit(autocommit);
if(getVersionNumber() >= 11202)
{
minVcsBindSize = 4001;
maxRawBytesSql = 4000;
maxRawBytesPlsql = 32766;
maxVcsCharsSql = 32766;
maxVcsNCharsSql = 32766;
maxVcsBytesPlsql = 32766;
maxIbtVarcharElementLength = 32766;
endToEndMaxLength[0] = 64;
endToEndMaxLength[1] = 64;
endToEndMaxLength[2] = 64;
endToEndMaxLength[3] = 64;
} else
if(getVersionNumber() >= 11000)
{
minVcsBindSize = 4001;
maxRawBytesSql = 4000;
maxRawBytesPlsql = 32766;
maxVcsCharsSql = 32766;
maxVcsNCharsSql = 32766;
maxVcsBytesPlsql = 32766;
maxIbtVarcharElementLength = 32766;
endToEndMaxLength[0] = 32;
endToEndMaxLength[1] = 64;
endToEndMaxLength[2] = 64;
endToEndMaxLength[3] = 48;
} else
if(getVersionNumber() >= 10000)
{
minVcsBindSize = 4001;
maxRawBytesSql = 2000;
maxRawBytesPlsql = 32512;
maxVcsCharsSql = 32766;
maxVcsNCharsSql = 32766;
maxVcsBytesPlsql = 32512;
maxIbtVarcharElementLength = 32766;
endToEndMaxLength[0] = 32;
endToEndMaxLength[1] = 64;
endToEndMaxLength[2] = 64;
endToEndMaxLength[3] = 48;
} else
if(getVersionNumber() >= 9200)
{
minVcsBindSize = 4001;
maxRawBytesSql = 2000;
maxRawBytesPlsql = 32512;
maxVcsCharsSql = 32766;
maxVcsNCharsSql = 32766;
maxVcsBytesPlsql = 32512;
maxIbtVarcharElementLength = 32766;
endToEndMaxLength[0] = 32;
endToEndMaxLength[1] = 64;
endToEndMaxLength[2] = 64;
endToEndMaxLength[3] = 48;
} else
{
minVcsBindSize = 4001;
maxRawBytesSql = 2000;
maxRawBytesPlsql = 2000;
maxVcsCharsSql = 4000;
maxVcsNCharsSql = 4000;
maxVcsBytesPlsql = 4000;
maxIbtVarcharElementLength = 4000;
endToEndMaxLength[0] = 32;
endToEndMaxLength[1] = 64;
endToEndMaxLength[2] = 64;
endToEndMaxLength[3] = 48;
}
if(getVersionNumber() >= 10000)
retainV9BindBehavior = false;
initializeSetCHARCharSetObjs();
if(implicitStatementCacheSize > 0)
{
setStatementCacheSize(implicitStatementCacheSize);
setImplicitCachingEnabled(true);
}
}
catch(SQLException sqlexception)
{
lifecycle = 2;
try
{
logoff();
}
catch(SQLException sqlexception1) { }
lifecycle = 4;
throw sqlexception;
}
txnMode = 0;
}
进行了一系列的初始化工作 最重要的还是
logon();
回到子类 T4CConnection的logon()方法
void logon()
throws SQLException
{
SQLException sqlexception = null;
try
{
if(isLoggedOn)
{
SQLException sqlexception1 = DatabaseError.createSqlException(getConnectionDuringExceptionHandling(), 428);
sqlexception1.fillInStackTrace();
throw sqlexception1;
}
if(database == null)
database = "localhost:1521:orcl";
connect(database);
all8 = new T4C8Oall(this);
okpn = new T4CTTIokpn(this);
close8 = new T4C8Oclose(this);
sto = new T4CTTIsto(this);
spfp = new T4CTTIspfp(this);
commoncall = new T4C7Ocommoncall(this);
describe = new T4C8Odscrarr(this);
bfileMsg = new T4C8TTIBfile(this);
blobMsg = new T4C8TTIBlob(this);
clobMsg = new T4C8TTIClob(this);
otxen = new T4CTTIOtxen(this);
otxse = new T4CTTIOtxse(this);
oping = new T4CTTIoping(this);
k2rpc = new T4CTTIk2rpc(this);
oses = new T4CTTIoses(this);
okeyval = new T4CTTIokeyval(this);
oxssro = new T4CTTIoxssro(this);
oxsspo = new T4CTTIoxsspo(this);
oxsscs = new T4CTTIoxsscs(this);
xsnsop = new T4CTTIxsnsop(this);
aqe = new T4Caqe(this);
aqdq = new T4Caqdq(this);
oscid = new T4CTTIoscid(this);
LOGON_MODE = 0L;
if(internalLogon != null)
if(internalLogon.equalsIgnoreCase("sysoper"))
LOGON_MODE = 64L;
else
if(internalLogon.equalsIgnoreCase("sysdba"))
LOGON_MODE = 32L;
else
if(internalLogon.equalsIgnoreCase("sysasm"))
LOGON_MODE = 0x400000L;
else
if(internalLogon.equalsIgnoreCase("sysbackup"))
LOGON_MODE = 0x1000000L;
else
if(internalLogon.equalsIgnoreCase("sysdg"))
LOGON_MODE = 0x2000000L;
else
if(internalLogon.equalsIgnoreCase("syskm"))
LOGON_MODE = 0x4000000L;
if(prelimAuth)
LOGON_MODE = LOGON_MODE | 128L;
auth = new T4CTTIoauthenticate(this, resourceManagerId, serverCompileTimeCapabilities);
if(userName != null && userName.length() != 0)
try
{
auth.doOSESSKEY(userName, LOGON_MODE);
}
catch(SQLException sqlexception2)
{
if(sqlexception2.getErrorCode() == 1017)
{
sqlexception = sqlexception2;
userName = null;
} else
{
throw sqlexception2;
}
}
auth.doOAUTH(userName, password, LOGON_MODE);
sessionId = getSessionId();
serialNumber = getSerialNumber();
internalName = auth.internalName;
externalName = auth.externalName;
instanceName = sessionProperties.getProperty("AUTH_INSTANCENAME");
if(!prelimAuth)
{
T4C7Oversion t4c7oversion = new T4C7Oversion(this);
t4c7oversion.doOVERSION();
byte abyte0[] = t4c7oversion.getVersion();
try
{
databaseProductVersion = new String(abyte0, "UTF8");
}
catch(UnsupportedEncodingException unsupportedencodingexception)
{
SQLException sqlexception6 = DatabaseError.createSqlException(getConnectionDuringExceptionHandling(), unsupportedencodingexception);
sqlexception6.fillInStackTrace();
throw sqlexception6;
}
versionNumber = t4c7oversion.getVersionNumber();
} else
{
versionNumber = 0;
}
isLoggedOn = true;
if(getVersionNumber() < 11000)
enableTempLobRefCnt = false;
}
catch(NetException netexception)
{
SQLException sqlexception4 = DatabaseError.createSqlException(getConnectionDuringExceptionHandling(), netexception);
sqlexception4.fillInStackTrace();
throw sqlexception4;
}
catch(IOException ioexception)
{
handleIOException(ioexception);
SQLException sqlexception5 = DatabaseError.createSqlException(getConnectionDuringExceptionHandling(), ioexception);
sqlexception5.fillInStackTrace();
throw sqlexception5;
}
catch(SQLException sqlexception3)
{
if(sqlexception != null)
sqlexception3.initCause(sqlexception);
try
{
net.disconnect();
}
catch(Exception exception) { }
isLoggedOn = false;
throw sqlexception3;
}
}
哦 重点是它
connect(database);
void connect(String s)
throws IOException, SQLException
{
if(s == null)
{
SQLException sqlexception = DatabaseError.createSqlException(getConnectionDuringExceptionHandling(), 433);
sqlexception.fillInStackTrace();
throw sqlexception;
}
Properties properties = new Properties();
if(thinNetProfile != null)
properties.setProperty("oracle.net.profile", thinNetProfile);
if(thinNetAuthenticationServices != null)
properties.setProperty("oracle.net.authentication_services", thinNetAuthenticationServices);
if(thinNetAuthenticationKrb5Mutual != null)
properties.setProperty("oracle.net.kerberos5_mutual_authentication", thinNetAuthenticationKrb5Mutual);
if(thinNetAuthenticationKrb5CcName != null)
properties.setProperty("oracle.net.kerberos5_cc_name", thinNetAuthenticationKrb5CcName);
if(thinNetEncryptionLevel != null)
properties.setProperty("oracle.net.encryption_client", thinNetEncryptionLevel);
if(thinNetEncryptionTypes != null)
properties.setProperty("oracle.net.encryption_types_client", thinNetEncryptionTypes);
if(thinNetChecksumLevel != null)
properties.setProperty("oracle.net.crypto_checksum_client", thinNetChecksumLevel);
if(thinNetChecksumTypes != null)
properties.setProperty("oracle.net.crypto_checksum_types_client", thinNetChecksumTypes);
if(thinNetCryptoSeed != null)
properties.setProperty("oracle.net.crypto_seed", thinNetCryptoSeed);
if(thinTcpNoDelay)
properties.setProperty("TCP.NODELAY", "YES");
if(thinReadTimeout != null)
properties.setProperty("oracle.net.READ_TIMEOUT", thinReadTimeout);
if(thinNetConnectTimeout != null)
properties.setProperty("oracle.net.CONNECT_TIMEOUT", thinNetConnectTimeout);
if(thinSslServerDnMatch != null)
properties.setProperty("oracle.net.ssl_server_dn_match", thinSslServerDnMatch);
if(walletLocation != null)
properties.setProperty("oracle.net.wallet_location", walletLocation);
if(walletPassword != null)
properties.setProperty("oracle.net.wallet_password", walletPassword);
if(thinSslVersion != null)
properties.setProperty("oracle.net.ssl_version", thinSslVersion);
if(thinSslCipherSuites != null)
properties.setProperty("oracle.net.ssl_cipher_suites", thinSslCipherSuites);
if(thinJavaxNetSslKeystore != null)
properties.setProperty("javax.net.ssl.keyStore", thinJavaxNetSslKeystore);
if(thinJavaxNetSslKeystoretype != null)
properties.setProperty("javax.net.ssl.keyStoreType", thinJavaxNetSslKeystoretype);
if(thinJavaxNetSslKeystorepassword != null)
properties.setProperty("javax.net.ssl.keyStorePassword", thinJavaxNetSslKeystorepassword);
if(thinJavaxNetSslTruststore != null)
properties.setProperty("javax.net.ssl.trustStore", thinJavaxNetSslTruststore);
if(thinJavaxNetSslTruststoretype != null)
properties.setProperty("javax.net.ssl.trustStoreType", thinJavaxNetSslTruststoretype);
if(thinJavaxNetSslTruststorepassword != null)
properties.setProperty("javax.net.ssl.trustStorePassword", thinJavaxNetSslTruststorepassword);
if(thinSslKeymanagerfactoryAlgorithm != null)
properties.setProperty("ssl.keyManagerFactory.algorithm", thinSslKeymanagerfactoryAlgorithm);
if(thinSslTrustmanagerfactoryAlgorithm != null)
properties.setProperty("ssl.trustManagerFactory.algorithm", thinSslTrustmanagerfactoryAlgorithm);
if(thinNetOldsyntax != null)
properties.setProperty("oracle.net.oldSyntax", thinNetOldsyntax);
if(thinNamingContextInitial != null)
properties.setProperty("java.naming.factory.initial", thinNamingContextInitial);
if(thinNamingProviderUrl != null)
properties.setProperty("java.naming.provider.url", thinNamingProviderUrl);
if(thinNamingSecurityAuthentication != null)
properties.setProperty("java.naming.security.authentication", thinNamingSecurityAuthentication);
if(thinNamingSecurityPrincipal != null)
properties.setProperty("java.naming.security.principal", thinNamingSecurityPrincipal);
if(thinNamingSecurityCredentials != null)
properties.setProperty("java.naming.security.credentials", thinNamingSecurityCredentials);
if(thinNetDisableOutOfBandBreak)
properties.setProperty("DISABLE_OOB", (new StringBuilder()).append("").append(thinNetDisableOutOfBandBreak).toString());
if(thinNetEnableSDP)
properties.setProperty("oracle.net.SDP", (new StringBuilder()).append("").append(thinNetEnableSDP).toString());
properties.setProperty("USE_ZERO_COPY_IO", (new StringBuilder()).append("").append(thinNetUseZeroCopyIO).toString());
properties.setProperty("FORCE_DNS_LOAD_BALANCING", (new StringBuilder()).append("").append(thinForceDnsLoadBalancing).toString());
properties.setProperty("ENABLE_JAVANET_FASTPATH", (new StringBuilder()).append("").append(enableJavaNetFastPath).toString());
properties.setProperty("oracle.jdbc.v$session.osuser", thinVsessionOsuser);
properties.setProperty("oracle.jdbc.v$session.program", thinVsessionProgram);
properties.setProperty("T4CConnection.hashCode", Integer.toHexString(hashCode()).toUpperCase());
properties.setProperty("oracle.net.keepAlive", Boolean.toString(keepAlive));
net = new NSProtocol();
net.connect(s, properties);
mare = new T4CMAREngine(net, enableJavaNetFastPath);
oer = new T4CTTIoer(this);
mare.setConnectionDuringExceptionHandling(this);
pro = new T4C8TTIpro(this);
pro.marshal();
serverCompileTimeCapabilities = pro.receive();
serverRuntimeCapabilities = pro.getServerRuntimeCapabilities();
short word0 = pro.getOracleVersion();
short word1 = pro.getCharacterSet();
short word2 = DBConversion.findDriverCharSet(word1, word0);
conversion = new DBConversion(word1, word2, pro.getncharCHARSET(), isStrictAsciiConversion, isQuickAsciiConversion);
mare.types.setServerConversion(word2 != word1);
DBConversion _tmp = conversion;
if(DBConversion.isCharSetMultibyte(word2))
{
DBConversion _tmp1 = conversion;
if(DBConversion.isCharSetMultibyte(pro.getCharacterSet()))
mare.types.setFlags((byte)1);
else
mare.types.setFlags((byte)2);
} else
{
mare.types.setFlags(pro.getFlags());
}
mare.conv = conversion;
T4C8TTIdty t4c8ttidty = new T4C8TTIdty(this, serverCompileTimeCapabilities, serverRuntimeCapabilities, logonCap != null && logonCap.trim().equals("o3"), thinNetUseZeroCopyIO);
t4c8ttidty.doRPC();
negotiatedTTCversion = serverCompileTimeCapabilities[7];
if(t4c8ttidty.jdbcThinCompileTimeCapabilities[7] < serverCompileTimeCapabilities[7])
negotiatedTTCversion = t4c8ttidty.jdbcThinCompileTimeCapabilities[7];
if(serverRuntimeCapabilities != null && serverRuntimeCapabilities.length > 6 && (serverRuntimeCapabilities[6] & T4C8TTIdty.KPCCAP_RTB_TTC_ZCPY) != 0 && thinNetUseZeroCopyIO && (net.getSessionAttributes().getNegotiatedOptions() & 0x40) != 0 && getDataIntegrityAlgorithmName().equals("") && getEncryptionAlgorithmName().equals(""))
useZeroCopyIO = true;
else
useZeroCopyIO = false;
if(serverCompileTimeCapabilities.length > 23 && (serverCompileTimeCapabilities[23] & 0x40) != 0 && (t4c8ttidty.jdbcThinCompileTimeCapabilities[23] & 0x40) != 0)
useLobPrefetch = true;
else
useLobPrefetch = false;
}
哦 其实看过joracle以前的jdbc源码 的 就不陌生了 前面文章中 就是用的老版本的jdbc
net = new NSProtocol();
net.connect(s, properties);
NSProtocol 在以前的jdbc版本中 也是它进行的封装 只不过 以前使用的是TTC7Protocal来调用它 现在使用T4CConnection来进行封装
看看NSProtocal的connect的方法吧
public void connect(String s, Properties properties)
throws IOException, NetException
{
if(sAtts.connected)
throw new NetException(201);
if(s == null)
throw new NetException(208);
NVFactory nvfactory = new NVFactory();
NVNavigator nvnavigator = new NVNavigator();
Object obj4 = null;
String s1 = null;
addrRes = new AddrResolution(s, properties);
String s2 = (String)properties.get("DISABLE_OOB");
boolean flag = s2 != null && "true".equals(s2);
String s3 = (String)properties.get("USE_ZERO_COPY_IO");
boolean flag1 = true;
if(s3 != null && "false".equals(s3))
flag1 = false;
String s4 = (String)properties.get("ENABLE_JAVANET_FASTPATH");
boolean flag2 = false;
if(s4 != null && "true".equals(s4))
flag2 = true;
sAtts.enableJavaNetFastPath = flag2;
sAtts.traceId = (String)properties.get("T4CConnection.hashCode");
if(addrRes.connection_revised)
{
s = addrRes.getTNSAddress();
properties = addrRes.getUp();
}
sAtts.profile = new ClientProfile(properties);
establishConnection(s);
Object obj5 = null;
try
{
obj5 = Class.forName("oracle.net.ano.Ano").newInstance();
sAtts.anoEnabled = true;
}
catch(Exception exception)
{
sAtts.anoEnabled = false;
}
if(obj5 != null)
{
((Ano)obj5).init(sAtts);
sAtts.ano = (Ano)obj5;
sAtts.anoEnabled = true;
}
label0:
do
{
IOException ioexception = null;
ConnectPacket connectpacket = new ConnectPacket(sAtts, !flag, flag1);
packet = new Packet(sAtts, sAtts.getSDU());
try
{
connectpacket.send();
packet.receive();
}
catch(InterruptedIOException interruptedioexception)
{
throw interruptedioexception;
}
catch(IOException ioexception1)
{
packet.type = 4;
ioexception = ioexception1;
}
switch(packet.type)
{
case 2: // '\002'
AcceptPacket acceptpacket = new AcceptPacket(packet);
break label0;
case 5: // '\005'
RedirectPacket redirectpacket = new RedirectPacket(packet);
ConnOption connoption = sAtts.cOption;
addrRes.connection_redirected = true;
sAtts.cOption.nt.disconnect();
sAtts = establishConnection(redirectpacket.getData());
sAtts.cOption.restoreFromOrigCoption(connoption);
break;
case 4: // '\004'
RefusePacket refusepacket = new RefusePacket(packet);
sAtts.cOption.nt.disconnect();
sAtts.cOption = null;
establishConnection(null);
if(sAtts.cOption == null)
{
if(ioexception != null)
throw ioexception;
try
{
NVPair nvpair = nvnavigator.findNVPairRecurse(nvfactory.createNVPair(refusepacket.getData()), "ERROR");
if(nvpair != null)
{
NVPair nvpair1 = nvnavigator.findNVPairRecurse(nvpair, "CODE");
if(nvpair1 != null)
s1 = nvpair1.valueToString();
}
}
catch(NLException nlexception) { }
throw new NetException(s1 != null ? Integer.parseInt(s1) : 206, "");
}
break;
case 11: // '\013'
if((packet.flags & 8) == 8)
sAtts.renegotiateSSLSession();
break;
case 3: // '\003'
case 6: // '\006'
case 7: // '\007'
case 8: // '\b'
case 9: // '\t'
case 10: // '\n'
default:
sAtts.cOption.nt.disconnect();
throw new NetException(205);
}
} while(true);
setNetStreams();
sAtts.connected = true;
sAtts.nt.setReadTimeoutIfRequired(properties);
String s5 = (String)sAtts.nt.getOption(6);
if(s5 != null && s5.equalsIgnoreCase("false"))
throw new NetException(405);
if(!sAtts.noAnoServices && sAtts.ano != null)
{
sAtts.ano.negotiation(addrRes.connection_redirected);
String s6 = (String)sAtts.nt.getOption(2);
if(s6 != null && s6.equals("TRUE"))
try
{
Method method = sAtts.ano.getClass().getMethod("getEncryptionAlg", (Class[])null);
if(method.invoke(sAtts.ano, (Object[])null) != null)
throw new NetException(406);
}
catch(Exception exception1) { }
}
addrRes.connection_redirected = false;
packet = null;
Object obj = null;
Object obj1 = null;
Object obj3 = null;
Object obj2 = null;
}
重点还是它 establishConnection(s); 和以前一样
private SessionAtts establishConnection(String s)
throws NetException, IOException
{
sAtts.cOption = addrRes.resolveAndExecute(s);
if(sAtts.cOption == null)
return null;
sAtts.nt = sAtts.cOption.nt;
sAtts.ntInputStream = sAtts.cOption.nt.getInputStream();
sAtts.ntOutputStream = sAtts.cOption.nt.getOutputStream();
sAtts.setTDU(sAtts.cOption.tdu);
sAtts.setSDU(sAtts.cOption.sdu);
if(sAtts.attemptingReconnect)
{
sAtts.nsOutputStream.reinitialize(sAtts);
sAtts.nsInputStream.reinitialize(sAtts);
if(mkPkt != null)
mkPkt.reinitialize(sAtts);
} else
{
sAtts.nsOutputStream = new NetOutputStream(sAtts, 255);
sAtts.nsInputStream = new NetInputStream(sAtts);
}
return sAtts;
}
这里就是
sAtts.cOption = addrRes.resolveAndExecute(s);
进行了连接
public ConnOption resolveAndExecute(String s)
throws NetException, IOException
{
ConnStrategy connstrategy = cs;
if(s != null)
{
cs = new ConnStrategy(up);
if(connection_redirected)
{
cs.sdu = connstrategy.sdu;
cs.tdu = connstrategy.tdu;
cs.retryCount = connstrategy.retryCount;
cs.socketOptions = connstrategy.socketOptions;
cs.reuseOpt = true;
}
if(s.indexOf(')') == -1)
{
s = s.trim();
if(s.startsWith("//") || s.matches("[\\w]*") || s.matches("[\\[[\\w:]*\\]]") || s.matches("[[\\w-]\\.]*:[\\d]*/[[\\w\\$\\#]\\.]*(?i)(:pooled)?(?-i)"))
{
String s1 = System.getProperty("oracle.net.tns_admin");
NameResolver nameresolver = NameResolverFactory.getNameResolver(s1, cs.getOSUsername(), cs.getProgramName());
s = s.replaceAll("#", "\\\\#");
TNSAddress = nameresolver.resolveName(s);
resolveAddrTree(TNSAddress);
} else
{
resolveSimple(s);
}
} else
if(newSyntax)
resolveAddrTree(s);
else
resolveAddr(s);
} else
if(cs == null || !cs.hasMoreOptions())
return null;
return cs.execute();
}
看到最后一句话
return cs.execute();
调用的是 ConnStrategy的execute方法 看看吧
public ConnOption execute()
throws NetException
{
Object obj = null;
if(connectTimeout == -1)
{
if(socketOptions.get(Integer.valueOf(2)) == null)
socketOptions.put(Integer.valueOf(2), Integer.toString(60000));
} else
{
socketOptions.put(Integer.valueOf(2), Integer.toString(connectTimeout));
}
if(retryCount < 0)
retryCount = 0;
socketOptions.put(Integer.valueOf(17), Integer.toString(retryCount));
for(int i = lastRetryCounter; i <= retryCount; i++)
{
while(nextOptToTry < cOpts.size())
try
{
copt = (ConnOption)cOpts.elementAt(nextOptToTry);
copt.connect(socketOptions);
copt.sdu = sdu;
copt.tdu = tdu;
optFound = true;
nextOptToTry++;
lastRetryCounter = i;
return copt;
}
catch(IOException ioexception)
{
nextOptToTry++;
obj = ioexception;
}
nextOptToTry = 0;
}
if(obj == null)
throw new NetException(20);
else
throw (NetException)(new NetException(20)).initCause(((Throwable) (obj)));
}
有一句
copt.connect(socketOptions);
调用ConnOption的connect方法
public void connect(Properties properties)
throws IOException
{
try
{
populateProtocol();
if(protocol == null)
throw new NetException(501);
}
catch(NLException nlexception)
{
throw new NetException(501);
}
nt = getNT(properties);
nt.connect();
}
看到最后两句
nt = getNT(properties);
nt.connect();
private NTAdapter getNT(Properties properties)
throws NetException
{
try
{
if(protocol.equalsIgnoreCase("tcp"))
{
nt = new TcpNTAdapter(addr, properties);
origServiceName = service_name;
origSid = sid;
} else
if(protocol.equalsIgnoreCase("tcps"))
{
nt = new TcpsNTAdapter(addr, properties);
origSSLServerCertDN = sslServerCertDN;
origServiceName = service_name;
origSid = sid;
String as[] = {
origSSLServerCertDN, origServiceName, origSid
};
nt.setOption(8, as);
} else
if(protocol.equalsIgnoreCase("sdp"))
{
nt = new SdpNTAdapter(addr, properties);
origServiceName = service_name;
origSid = sid;
} else
{
throw new NetException(21);
}
}
catch(NLException nlexception)
{
throw new NetException(501);
}
catch(Exception exception)
{
throw new NetException(21);
}
return nt;
}
看到如果协议是tcp的话 即会创建一个TcpNTAdapter
接着上面ConnOption的connect里面 还有一句
nt.connect();
上面再创建了TcpNTAdapter后 则会调用其connect方法
public void connect()
throws IOException
{
String s = (String)socketOptions.get(Integer.valueOf(2));
boolean flag = Boolean.parseBoolean((String)socketOptions.get(Integer.valueOf(18)));
InetAddress ainetaddress[] = InetAddress.getAllByName(host);
if(flag && ainetaddress.length > 1)
ainetaddress = getAddressesInCircularOrder(host, ainetaddress);
int i = ainetaddress.length;
int j = 0;
do
{
InetAddress inetaddress = ainetaddress[j];
j++;
i--;
socket = new Socket();
try
{
socket.connect(new InetSocketAddress(inetaddress, port), Integer.parseInt(s));
break;
}
catch(IOException ioexception)
{
try
{
if(socket != null)
socket.close();
}
catch(Exception exception) { }
if(i <= 0)
throw ioexception;
}
} while(j < ainetaddress.length);
setOption(3, s);
setSocketOptions();
}
则看到 有一行 不就是一直想看到的socket么
socket.connect(new InetSocketAddress(inetaddress, port), Integer.parseInt(s));
到此 ojdbc6的驱动注册与连接 就搞定了
其实这里面还有太多东西需要去学习了 哎 慢慢来 记录学习的脚步 加油 吃饭去了