在前面的博客里面提到了 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的驱动注册与连接 就搞定了
其实这里面还有太多东西需要去学习了 哎 慢慢来 记录学习的脚步 加油 吃饭去了