Oracle JDBC 入门之深入浅出

时间:2021-07-11 16:23:59

一、JDBC概述

什么是JDBC
JDBC:JAVA DataBase Connction,同时也是SUN的注册的一个商标。JDBC是JAVA访问各种数据库的事实标准。
对于SUN:JDBC是规定的一套接口和类,对于厂商:必须提供JDBC实现,又叫“驱动”。

简单的说,SUN提供了一套接口和类,规定了JAVA连数据库的一整套接口和类。而各数据库应用厂商,必须实现JDBC相应接口以便采用统一的方法来操作数据库。进行CRUD的操作。

二、Oracle JDBC 相关介绍

本遍介绍java如何连接Oracle 11g数据库,关于Oracle11g 数据库的下载安装方法,请参照Oracle 11g 安装 图文 攻略http://blog.csdn.net/chenshufei2/article/details/7905335  。

安装后,Oracle11g后,必须找到Oracle的jdbc包,即ojdbc.jar。这里使用ojdbc6.jar。  其实这个jar包,可以在Oracle安装目录的:Oracle基目录\product\11.2.0\dbhome_1\jdbc\lib,找到相应的jdbc jar包。若使用Txt文本连接数据库的朋友,可以将此路径配置到环境变量中。使用IDE的朋友可以将此jar包复制到Referenced Libraries中。

通常,java要进行连接数据库,必须提供 JDBC的Driver类和URL数据库的连接实例用户名密码及端口号,然后由此Driver来管理得到Connection进行对数据库的操作。

Oracle 11g中, JDBC Driver类是:oracle.jdbc.OracleDriver。而URL是jdbc:oracle:thin:@主机名或IP:1521:orcl 其中orcl是默认的数据库实例,若项目有自定义的数据库实例,应该将orcl改成XXXX自定义新建的数据库。

三、示例代码分析:

String dbUrl = "jdbc:oracle:thin:@127.0.0.1:1521:orcl" ;
Connection con = null ;
Statement statm = null;
String sql = "Select UserName, Age From temp_1";
try{
/*OracleDriver od = (OracleDriver)DriverManager.getDriver(dbUrl);
System.out.println("------oracel main start---");
od.main(args);
System.out.println("------oracel main end---");*/
Class.forName("oracle.jdbc.OracleDriver"); //这里也可以去掉,因为getConnection方便中,没有注册会根据URL进行loadInitialDrivers呢。
con = DriverManager.getConnection(dbUrl, "scott", "chen");
//底层原理,若未进行Class.forName注册:
/**
* 1.先执行到 loadInitialDrivers()方法中,而此方法中有 DriverService ds = new DriverService();java.security.AccessController.doPrivileged(ds);
* 上面的doPrivileged是本地方法,可以调用DriverService类中的run方法。类似Thread中run方法被调用原理。 * 2. DriverService类的run方法Iterator ps = Service.providers(java.sql.Driver.class);,这个ps是个底层产生个很特殊的迭代器,因为providers方法执行后,
* 它后面的while可以循环两个两个不同的oracle,且在next时,这个自定义的迭代器,又会回调 DriverManager类的registerDriver(java.sql.Driver driver)方法。
* 来把需要进行的驱动类进行注册。
*
* 当然也可以直接进行注册比如在getConnection前面进行 class.forName("oracle.jdbc.OracleDriver"),而可以明确的是forName加载时会加载类的静态代码块。
* 而OracleDriver类有如下静态块,类装配时将会初始化如下代码块:
*
static{
try
{
if (defaultDriver == null)
{
defaultDriver = new oracle.jdbc.OracleDriver();
DriverManager.registerDriver(defaultDriver); //注意这里就进行了注册了。告诉JVM要使用的驱动Driver是OracleDriver的呢。
}

AccessController.doPrivileged(new PrivilegedAction()
{
public java.lang.Object run()
{
OracleDriver.registerMBeans();
return null;
}

});
Timestamp localTimestamp = Timestamp.valueOf("2000-01-01 00:00:00.0");
}catch(...){
...
}

...
}
而这种方式,肯定会把上面没有写。直接在DriverMananger.getCon..时,再loadInitialDrivers()遍历查找url相符的jdbc driver.
*
*/
//registerDriver(java.sql.Driver driver)
System.out.println(6456081.0/1024);
statm = con.createStatement();
ResultSet rs = statm.executeQuery(sql);
while(rs.next()){
String UserName = rs.getString("UserName");
int Age = rs.getInt("Age");
System.out.println("UserName="+UserName+",Age="+Age);
}

}catch(Exception e){
e.printStackTrace();
}finally{
try {
if (null != statm)
statm.close();
if (null != con)
con.close();
} catch (Exception e) {
e.printStackTrace();
System.out.println("关流失败哦");
}


}

}


上面提到,其实也可以不用显示的进行注册Driver,即不用Class.forName("oracle.jdbc.OracleDriver");进行显示注册的。也可以通过getConnection方法在进行loadInitialDrivers方法是,根据URL找到已有lib中jar包可解析URL的Driver。

当然,建议还是Class.forName进行注册Driver, 那么看起来Class.forName之后,没有newInstance,没有产生对象也没调用方法。是如何实现注册的呢?

其实Class.forName,虽然没有newInstance创建出实例对象,但是它进行了加载装配,也就是说会进行静态初始化,这就是关键之处。那么下面简单的剖析下这些数据库厂商Driver类,以OracleDriver为例,此类中存在如下的静态代码块:

static{
try
{
if (defaultDriver == null)
{
defaultDriver = new oracle.jdbc.OracleDriver();
DriverManager.registerDriver(defaultDriver); //注意这里就进行了注册了。告诉JVM要使用的驱动Driver是OracleDriver的呢。
}

AccessController.doPrivileged(new PrivilegedAction()
{
public java.lang.Object run()
{
OracleDriver.registerMBeans();
return null;
}

});
Timestamp localTimestamp = Timestamp.valueOf("2000-01-01 00:00:00.0");
}catch(...){
...
}

...
}


那么,通过在静态代码块中,new出 OracleDriver实例对象,并注册到DriverMananger类。那么下面的DriverManger类,用getConnection,就可以通过各数据库厂商提供的Driver如OracleDriver(各厂商的Driver 必须要实现Driver接口,并实现connect方法的。)的 Connection connect(String paramString, Properties paramProperties)方法得到各自厂商实现的Connection对象了。

这就是Class.forName及 DriverManange.getConnection的关键。

至于JDBC中,得到Connection后的 createStatement。用Statement的executeQuery得到ResultSet进行,那某个条件的表进行记录集的查找,就不重点介绍了。