0

在 JDBC 中,我们主要使用 Connection、Statement 和 ResultSet 这三个接口来连接和执行 DB 中的语句。但是它们对应的对象稍后用于运行 createStatement()、executeQuery()、next() 等方法。哪个类实现了这些方法?为什么它被称为连接对象而不是实现的类对象?

4

5 回答 5

2

你实际上并没有这样做

Connection conn = new Connection();

你做类似的事情

Connection conn = DriverManager.getConnection(
     DB_PATH + "?user=" + USER_NAME + "&password=" + USER_PASS); 
Statement statement = conn.createStatement();
ResultSet resultSet = statement.executeQuery(query);

但是要直接回答您的问题不,您不能实例化Interface您必须使用或使用代理implements的类。Interface

于 2012-04-26T17:13:46.893 回答
2

在 JDBC 中,您首先通过调用注册驱动程序

Class.forName('classname')

它加载数据库类并注册该类DriverManager

当你说DriverManager.getConnection() - 它返回你java.sql.Connection(根据规范的合同)

哪个类实现了这些方法?

实际实现由数据库供应商提供,例如 Oracle、MySQL。

为什么它被称为连接对象而不是实现的类对象?

因为您编码到接口而不是实现(良好的编码实践)。

如果你愿意,你可以在供应商 jar 中查找并找到哪个类实现 Connection 然后而不是

Connection connection = DriverManager.getConnection()

你可以写

VendorConnectionImpl vendorConnection = (VendorConnectionImpl)DriverManager.getConnection()

上面的方法会起作用,但它会绑定你与那个特定的实现。

如果你想从 vendor1 移动到 vendor2,你不能这样做,首先你必须根据 vendor2 API 更改上面的代码,但是如果你使用第一种方法,你可以从 Vendor 移动到 Vendor,而无需更改代码。

于 2012-04-26T17:25:04.043 回答
0

您不能实例化接口类。您要么自己实现该接口,要么使用Proxy创建所述接口的实例,该实例将所有调用委托给提供的InvocationHandler

于 2012-04-26T17:09:45.940 回答
0

这些人正在回答你的问题,但我认为你没有从评论中得到它。

您需要通过创建自己的类来实际实现接口。因此,创建一个实现接口的类,包含正确的抽象方法,然后将您想要的任何内容添加到新类中的功能中。然后,您将实例化该类以使用这些函数。

接口就像一个编程“合同”,它的存在是为了确保使用的任何扩展接口的类都满足某些功能,但是,你不能实例化接口本身来使用它的方法,你可以在你的方法中继承/覆盖它们新班级。在您覆盖新类中的抽象方法后,您可以编写任何您希望特定接口扩展类执行的其他操作。

http://www.javabeginner.com/learn-java/java-abstract-class-and-interfacehttp://www.javaworld.com/javaworld/javaqa/2001-04/03-qa-0420-abstract。 html 将让您阅读这些主题。

于 2012-04-26T17:23:35.350 回答
0

希望下面的解释会有所帮助。

Q:驱动Connection实现从何而来?以及Statement和ResultSet的实现?

Class.forName("com.mysql.jdbc.Driver").newInstance();
// String url="jdbc:mysql://localhost:3306/mydb?user=root&password=root";
Connection con = DriverManager.getConnection(url);

小提示:一旦 DriverManager 类被加载(初始化),驱动程序实现就会被加载。

以mysql-connector-java:5.1.36的源码为例。

com.mysql.jdbc.Driver类扩展了NonRegisteringDriver类,其中有一个名为connect()的方法,它返回一个 Connection 实例。
注意NonRegisteringDriver的registeredDrivers字段

public class Driver extends NonRegisteringDriver implements java.sql.Driver {
...
public java.sql.Connection connect(String url, Properties info) throws SQLException {

● mysql驱动被注册,驱动被添加到registeredDrivers

Class.forName("com.mysql.jdbc.Driver");
...
java.sql.DriverManager.registerDriver(new Driver()); // from com.mysql.jdbc.Driver
...
registeredDrivers.addIfAbsent(new DriverInfo(driver, da));  // mysql driver instance is added to registeredDrivers

从现在开始,JDBC就知道有一种 JDBC 实现,即 mysql。
● 然后创建连接:

Connection con = DriverManager.getConnection(url);

● 关注DriverManager.getConnection的源码
注意注册
的Drivers 这里的connection实现是由aDriver.driver.connect创建的

for(DriverInfo aDriver : registeredDrivers) {
...
     Connection con = aDriver.driver.connect(url, info);
...
}

● 由于已经找到了mysql的connection实现,所以通过挖掘mysql-connector-java:5.1.36的源码也可以找到StatementResultSet的实现

Statement stmt = con.createStatement();
// String sql = "select * from user";
ResultSet rs=stmt.executeQuery(sql);

至于JDBC 4,在加载 DriverManager 类时,会自动从类路径中检测驱动程序实现:
DriverManager.java#l101

static {
    loadInitialDrivers();
    println("JDBC DriverManager initialized");
}

...

private static void loadInitialDrivers() {
...
    ServiceLoader<Driver> loadedDrivers = ServiceLoader.load(Driver.class);
...
}

文件 mysql-connector-java-5.1.36.jar!/ META-INF/services/java.sql.Driver 的内容:

com.mysql.jdbc.Driver
com.mysql.fabric.jdbc.FabricMySQLDriver
于 2020-07-15T15:26:27.320 回答