oracle jdbc连接数据库的源代码分析之获取连接

由于最近的工作需要,需要对jdbc的数据库连接的内部逻辑做研究,在此将研究过程中的一些关键函数的内容在此以日志的形式保存下来,以便后续继续完善。

1、一段字符串获取它的UTF8的字节长度函数:

private static int stringUTF8Length(char ac[])
    {
        int i = 0;
        int j = ac.length;
        for(int k = 0; k < j; k++)
        {
            char c = ac[k];
            if(c >= 0 && c <= '\177')
                i++;
            else
            if(c >= '\200' && c <= '\u07FF')
                i += 2;
            else
                i += 3;
        }

        return i;
    }

2、java中的字节数组转换成Utf8格式的字节:

private static byte[] javaCharsToUtf8Bytes(char ac[])
    {
        int k = ac.length;
        int l = stringUTF8Length(ac);
        byte abyte0[] = new byte[l];
        int i = 0;
        int j = 0;
        for(; i < k; i++)
        {
            char c = ac[i];
            if((c & 0xff80) == 0)
                abyte0[j++] = (byte)c;
            else
            if((c & 0xf800) == 0)
            {
                abyte0[j++] = (byte)(0xc0 | c >> 6 & 0x1f);
                abyte0[j++] = (byte)(0x80 | c & 0x3f);
            } else
            {
                abyte0[j++] = (byte)(0xe0 | c >> 12 & 0xf);
                abyte0[j++] = (byte)(0x80 | c >> 6 & 0x3f);
                abyte0[j++] = (byte)(0x80 | c & 0x3f);
            }
        }

        return abyte0;
    }

3、 DriverManager.getConnection(url,"system","****")的内部逻辑如下:

首先调用了如下的方法返回了一个连接:
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 = oracleAcceptsURL(s);
        if(i == 1)
            return null;
        if(i == 2)
        {
            DBError.throwSqlException(67);
            return null;
        }
        Hashtable hashtable = parseUrl(s);
        if(hashtable == null)
            return null;
        String s2 = properties.getProperty("user");
        String s3 = properties.getProperty("password");
        String s4 = properties.getProperty("database");
        if(s4 == null)
            s4 = properties.getProperty("server");
        if(s2 == null)
            s2 = (String)hashtable.get("user");
        s2 = parseLoginOption(s2, properties);
        if(s3 == null)
            s3 = (String)hashtable.get("password");
        if(s4 == null)
            s4 = (String)hashtable.get("database");
        String s5 = (String)hashtable.get("protocol");
        properties.put("protocol", s5);
        if(s5 == null)
        {
            DBError.throwSqlException(40, "Protocol is not specified in URL");
            return null;
        }
        String s6 = properties.getProperty("dll");
        if(s6 == null)
            properties.put("dll", "ocijdbc9");
        String s7 = properties.getProperty("prefetch");
        if(s7 == null)
            s7 = properties.getProperty("rowPrefetch");
        if(s7 == null)
            s7 = properties.getProperty("defaultRowPrefetch");
        if(s7 != null && Integer.parseInt(s7) <= 0)
            s7 = null;
        String s8 = properties.getProperty("batch");
        if(s8 == null)
            s8 = properties.getProperty("executeBatch");
        if(s8 == null)
            s8 = properties.getProperty("defaultExecuteBatch");
        if(s8 != null && Integer.parseInt(s8) <= 0)
            s8 = null;
        String s9 = properties.getProperty("remarks");
        if(s9 == null)
            s9 = properties.getProperty("remarksReporting");
        String s10 = properties.getProperty("synonyms");
        if(s10 == null)
            s10 = properties.getProperty("includeSynonyms");
        String s11 = properties.getProperty("restrictGetTables");
        String s12 = properties.getProperty("fixedString");
        String s13 = properties.getProperty("dataSizeUnits");
        String s14 = properties.getProperty("AccumulateBatchResult");
        if(s14 == null)
            s14 = "true";
        Enumeration enumeration;
        for(enumeration = DriverManager.getDrivers(); enumeration.hasMoreElements();)
        {
            Driver driver = (Driver)enumeration.nextElement();
            if(driver instanceof OracleDriver)
                break;
        }

        while(enumeration.hasMoreElements()) 
        {
            Driver driver1 = (Driver)enumeration.nextElement();
            if(driver1 instanceof OracleDriver)
                DriverManager.deregisterDriver(driver1);
        }
        Connection connection = getConnectionInstance(s5, s, s2, s3, s4, properties);
        if(s7 != null)
            ((oracle.jdbc.driver.OracleConnection)connection).setDefaultRowPrefetch(Integer.parseInt(s7));
        if(s8 != null)
            ((oracle.jdbc.driver.OracleConnection)connection).setDefaultExecuteBatch(Integer.parseInt(s8));
        if(s9 != null)
            ((oracle.jdbc.driver.OracleConnection)connection).setRemarksReporting(s9.equalsIgnoreCase("true"));
        if(s10 != null)
            ((oracle.jdbc.driver.OracleConnection)connection).setIncludeSynonyms(s10.equalsIgnoreCase("true"));
        if(s11 != null)
            ((oracle.jdbc.driver.OracleConnection)connection).setRestrictGetTables(s11.equalsIgnoreCase("true"));
        if(s12 != null)
            ((oracle.jdbc.driver.OracleConnection)connection).setDefaultFixedString(s12.equalsIgnoreCase("true"));
        if(s13 != null)
            ((oracle.jdbc.driver.OracleConnection)connection).setDataSizeUnits(s13);
        ((oracle.jdbc.driver.OracleConnection)connection).setAccumulateBatchResult(s14.equalsIgnoreCase("true"));
        hashtable = null;
        return connection;
    }
  • 在logon中设置了Oall7等参数
  • MEngine是在上面的connect(s2, properties)中初始化的
  •  public synchronized DBConversion logon(String s, String s1, String s2, Properties properties)
            throws SQLException, IOException
        {
            try
            {
                if(state > 0)
                    DBError.check_error(428);
                if(s == null || s1 == null)
                    DBError.check_error(433);
                if(s.length() == 0 || s1.length() == 0)
                    DBError.check_error(443);
                if(s2 == null)
                    s2 = "localhost:1521:orcl";
              <span style="color:#ff0000;">  connect(s2, properties);
                all7 = new Oall7(MEngine);</span>
                commoncall = new Ocommoncall(MEngine);
                opencall = new Oopen(MEngine);
                close = new Oclose(MEngine);
                TTCTypeRep _tmp = MEngine.types;
                describe = (Odscrarr)MEngine.types.newTTIFunObject((byte)1, MEngine);
                bfileMsg = new v8TTIBfile(MEngine);
                blobMsg = new v8TTIBlob(MEngine);
  • 39行的connectpacket.send()将数据库的连接字符串发送给服务器:
  • public void connect(String s, Properties properties)
            throws IOException, NetException
        {
            if(sAtts.connected)
                throw new NetException(201);
            if(s == null)
                throw new NetException(208);
            addrRes = new AddrResolution(s, properties);
            if(addrRes.connection_revised)
            {
                s = addrRes.getTNSAddress();
                properties = addrRes.getUp();
            }
            if(addrRes.jndi)
                sAtts.profile = new ClientProfile(properties, addrRes.getJndi());
            else
                sAtts.profile = new ClientProfile(properties);
            establishConnection(s);
            Object obj4 = null;
            try
            {
                obj4 = Class.forName("oracle.net.ano.Ano").newInstance();
                sAtts.anoEnabled = true;
            }
            catch(Exception _ex)
            {
                sAtts.anoEnabled = false;
            }
            if(obj4 != null)
            {
                ((Ano)obj4).init(sAtts);
                sAtts.ano = (Ano)obj4;
                sAtts.anoEnabled = true;
            }
    label0:
            do
            {
                ConnectPacket connectpacket = new ConnectPacket(sAtts);
                connectpacket.send();
                packet = new Packet(sAtts);
                packet.receive();
                switch(packet.type)
                {
                case 2: // '\002'
                    AcceptPacket acceptpacket = new AcceptPacket(packet);
                    break label0;
    
                case 11: // '\013'
                    break;
    
                case 5: // '\005'
                    RedirectPacket redirectpacket = new RedirectPacket(packet);
                    sAtts.cOption.nt.disconnect();
                    sAtts = establishConnection(redirectpacket.getData());
                    break;
    
                case 4: // '\004'
                    RefusePacket refusepacket = new RefusePacket(packet);
                    throw new NetException(206, refusepacket.getData());
    
                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;
            if(sAtts.ano != null)
                sAtts.ano.negotiation();
            packet = null;
            Object obj = null;
            Object obj1 = null;
            Object obj3 = null;
            Object obj2 = null;
        }



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值