- 了解java的类型,当然是先看文档。
看javase1.9 文档,英文,阅读有些麻烦,就比对这翻译一下文档。
文档中第一行
Module java.sql
在1.9中oracle提出模块(Module)化,一种先进的设计理念,本人暂时不懂,所以在此不做解释,也不影响了解Connection 类型。
然后是
Package java.sql
Interface Connection
All Superinterfaces:
AutoCloseable, Wrapper
此处不做解释。
public interface Connection extends Wrapper, AutoCloseable
A connection (session) with a specific database. SQL statements are executed and results are returned within the context of a connection.
公共 接口 java.sql.Connection 继承 java.sql.Wrapper 和 java.lang.AutoCloseable
一个与指定类型数据库的连接(会话),在一个连接的上下文中sql 陈述(语句)被执行并且返回结果集
A Connection object's database is able to provide information describing its tables, its supported SQL grammar, its stored procedures, the capabilities of this connection, and so on. This information is obtained with the getMetaData method.
特定数据库的‘连接’可以提供表的描述信息,特定数据库 支持的sql语法,数据库的存储过程,连接容量,等等,这些信息可以通过getMetaData() 方法获得。
Class.forName("oracle.jdbc.driver.OracleDriver");
String url = "jdbc:oracle:thin:@192.168.12.26:1521:infa";
String user = "tdm_source";
String pwd = "tdm_source";
Connection conn = DriverManager.getConnection(url, user, pwd);
DatabaseMetaData dbmd = conn.getMetaData();
int nameLength = dbmd.getMaxTableNameLength();
System.out.println(nameLength);//30 (oracle中表名限定最大长度为 30字符)
以上这段落的说明对深入使用数据库的开发人员很有作用的.
2.以下内容是解释如何建立一次连接与其解释(已oracle为例)
在project中有
Class.forName("oracle.jdbc.driver.OracleDriver");
这一行代码笼统的说就是project中添加了oracle驱动后,可以将oracle.jdbc.driver包中的OracleDriver加载到虚拟机中.
这就是传说中的动态加载,即程序运行到或者说执行到这行代码的时候,将oracle.jdbc.driver.OracleDriver找到并从硬盘中加载到内存中(虚拟机的方法区也称永久代Permanent Generation),此段代码不运行则不加载。
第一步:
java.lang.Class中forName()方法的实现如下ClassLoader查找并加载了oracle.jdbc.driver.OracleDriver
@CallerSensitive
public static Class<?> forName(String arg) throws ClassNotFoundException {
Class arg0 = Reflection.getCallerClass();
return forName0(arg, true, ClassLoader.getClassLoader(arg0), arg0);
}
第二步:在加载oracle.jdbc.driver.OracleDriver过程中发现有如下的静态代码块(每种数据库的驱动都有以下静态代码块),可以看出new了一个oracle.jdbc.OracleDriver()并将defaultDriver对象传递给java.sql.DriverManager.registerDriver()方法
static {
try {
if(defaultDriver == null) {
defaultDriver = new oracle.jdbc.OracleDriver();
DriverManager.registerDriver(defaultDriver);
}
第三步:再来看一下java.sql.DriverManager.registerDriver()方法
public static synchronized void registerDriver(Driver arg) throws SQLException {
registerDriver(arg, (DriverAction)null);
}
到这里就在DriverManager里注册了oracle.jdbc.driver.OracleDriver对象(实例)
public static synchronized void registerDriver(Driver arg, DriverAction arg0) throws SQLException {
if(arg != null) {
registeredDrivers.addIfAbsent(new DriverInfo(arg, arg0));
println("registerDriver: " + arg);
} else {
throw new NullPointerException();
}
}
第四步:回到我们写的代码中DriverManager.getConnection(); 该方法只是做了一个重组,创建了Properties 类型的对象然后重载的另一个getConnection()方法
@CallerSensitive
public static Connection getConnection(String arg, String arg0, String arg1) throws SQLException {
Properties arg2 = new Properties();
if(arg0 != null) {
arg2.put("user", arg0);
}
if(arg1 != null) {
arg2.put("password", arg1);
}
return getConnection(arg, arg2, Reflection.getCallerClass());
}
第五步:getConnection(String arg, Properties arg0, Class
private static Connection getConnection(String arg, Properties arg0, Class<?> arg1) throws SQLException {
ClassLoader arg2 = arg1 != null?arg1.getClassLoader():null;
Class arg3 = DriverManager.class;
synchronized(DriverManager.class) {
if(arg2 == null) {
arg2 = Thread.currentThread().getContextClassLoader();
}
}
if(arg == null) {
throw new SQLException("The url cannot be null", "08001");
} else {
println("DriverManager.getConnection(\"" + arg + "\")");
SQLException arg9 = null;
Iterator arg4 = registeredDrivers.iterator();
while(true) {
while(arg4.hasNext()) {
DriverInfo arg5 = (DriverInfo)arg4.next();
if(isDriverAllowed(arg5.driver, arg2)) {
try {
println(" trying " + arg5.driver.getClass().getName());
Connection arg6 = arg5.driver.connect(arg, arg0);
if(arg6 != null) {
println("getConnection returning " + arg5.driver.getClass().getName());
return arg6;
}
} catch (SQLException arg7) {
if(arg9 == null) {
arg9 = arg7;
}
}
} else {
println(" skipping: " + arg5.getClass().getName());
}
}
if(arg9 != null) {
println("getConnection failed: " + arg9);
throw arg9;
}
println("getConnection: no suitable driver found for " + arg);
throw new SQLException("No suitable driver found for " + arg, "08001");
}
}
}