提到Connction,这个接口我们一定不陌生,它的源码也已经在代理模式一章出现过,这里我们再次让它出场,我依旧会删掉它的大部分方法,限于篇幅。
[java]
package java.sql;
import java.sql.PreparedStatement;
import java.sql.SQLException;
/**
*
A connection (session) with a specific
* database. SQL statements are executed and results are returned
* within the context of a connection.
*
*/
public interface Connection extends Wrapper {
Statement createStatement() throws SQLException;
PreparedStatement prepareStatement(String sql) throws SQLException;
}
package java.sql;
import java.sql.PreparedStatement;
import java.sql.SQLException;
/**
*
A connection (session) with a specific
* database. SQL statements are executed and results are returned
* within the context of a connection.
*
*/
public interface Connection extends Wrapper {
Statement createStatement() throws SQLException;
PreparedStatement prepareStatement(String sql) throws SQLException;
}
以上便是Connection接口,这里只留下了两个方法,这两个方法相信各位读者都非常熟悉,它们都是我们最经常用的方法之二。
以上两个接口作为JDBC API的一部分,它们相当于告诉了数据库生产厂商两个要求。
第一,数据库厂商要提供一个数据库驱动类,它的作用可以是可以创造数据库连接,而这个数据库连接向上转型为我们JDBC的Connection。
第二,数据库厂商要提供一个数据库连接的实现类,这个实现类可以执行具体数据库的各个操作,比如帮我们执行SQL,返回执行结果,关闭连接等等。
我们都知道mysql的驱动类位于com.mysql.jdbc.Driver,而mysql的connection实现类也在这个包中,名称是ConnectionImpl,而相应的oracle也有驱动类,位于oracle.jdbc.driver.OracleDriver,相应的oracle也有connection实现类,位于oracle.jdbc.OracleConnectionWrapper。一般每个数据库都会有一个Connection的扩展接口,这个接口的作用是提供使用者针对当前数据库特殊的操作。
这里我们忽略掉这些中间接口以及抽象类,我给出上述六个类的UML图,如果各位以前知道工厂方法模式的话,各位看一下,它们的关系是否很熟悉。
相信看完以后,如果你以前学习过甚至使用过工厂方法模式的话,会发现它们的关系不正是工厂方法模式吗?(特别备注,我的ROSE表示实现接口的时候,会是一条直线,LZ搞了很久也不知道哪的事,如果有哪位对ROSE很熟悉的读者,可以帮助下LZ。。。)
工厂方法模式就是提供一个抽象的工厂,一个抽象的产品,在上述当中相当于Driver(数据库连接工厂)和Connection(抽象产品),实现的一方需要提供一个具体的工厂类(比如mysql驱动)和一个具体的产品(比如mysql数据库连接)。
客户端调用时不依赖于具体工厂和产品(即到底是mysql驱动,mysql数据库连接还是oracle驱动,oracle连接,我们程序猿不需要管的,我们只管使用抽象的driver和connection,对吧?),而是依赖于抽象工厂和抽象产品完成工作。
各位可以看到我在类图里面加入了一个DriverManager,这个类相信各位也不陌生,这是我们天天打交道的类,虽说因为hibernate和ibatis的封装,或许我们不能经常看到,但LZ相信它活在每个程序猿的心中。
DriverMananger在这个设计当中扮演者一个管理者的角色,它帮我们管理数据库驱动,让我们不需要直接接触驱动接口,我们获取连接只需要和DriverManager打交道就可以,也就是说客户端依赖于DriverManager和Connection就可以完成工作,不再需要与Driver关联,所以上述说我们依赖于Driver和Connection,现在DriverManager帮我们管理Driver,那我们只需要依赖于DriverManager和Connection就可以了。
我在类图中拉出了DriverManager的方法,其中的registerDriver方法正是我们注册数据库驱动的入口。来看看mysql的Driver中做了什么,oracle类似。
[java]
public class Driver extends NonRegisteringDriver
implements java.sql.Driver
{
public Driver()
throws SQLException
{
}
static
{
try
{
DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
}
public class Driver extends NonRegisteringDriver
implements java.sql.Driver
{
public Driver()
throws SQLException
{
}
static
{
try
{
DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new Runtim