Việc sử dụng thực tế Class.forName (“oracle.jdbc.driver.OracleDriver”) trong khi kết nối với cơ sở dữ liệu là gì?


91

Lệnh gì sẽ

Class.forName("oracle.jdbc.driver.OracleDriver")

chính xác khi kết nối với cơ sở dữ liệu Oracle? Có cách nào khác để làm điều tương tự không?


6
Liên quan: stackoverflow.com/questions/5992126/loading-jdbc-driver Lưu ý rằng bạn chỉ cần gọi nó một lần , trong khi khởi động ứng dụng của bạn; bạn không cần phải gọi nó mọi lúc trước khi nhận được kết nối trong suốt vòng đời của ứng dụng.
BalusC

@BalusC Giả sử tôi có chi tiết kết nối của mình trong lớp riêng biệt Anơi tôi gọi Class.forName("oracle.jdbc.driver.OracleDriver")trong phương thức Akhởi tạo lớp và tôi tạo A'sđối tượng để lấy trường kết nối cho mỗi servlet nơi tôi cần kết nối thì java sẽ bỏ qua Class.forName("oracle.jdbc.driver.OracleDriver")hay sẽ tải lại?
Asif Mushtaq,

Câu trả lời:


68

Nó nhận được một tham chiếu đến đối tượng lớp với FQCN (tên lớp đủ điều kiện) oracle.jdbc.driver.OracleDriver.

Nó không "làm" bất cứ điều gì về mặt kết nối với cơ sở dữ liệu, ngoài việc đảm bảo rằng lớp được chỉ định được tải bởi trình nạp lớp hiện tại . Không có sự khác biệt cơ bản giữa cách viết

Class<?> driverClass = Class.forName("oracle.jdbc.driver.OracleDriver");
// and
Class<?> stringClass = Class.forName("java.lang.String");

Class.forName("com.example.some.jdbc.driver")cuộc gọi hiển thị trong mã kế thừa sử dụng JDBC vì đó là cách để tải trình điều khiển JDBC .

Từ Hướng dẫn Java :

Trong các phiên bản trước của JDBC, để có được kết nối, trước tiên bạn phải khởi tạo trình điều khiển JDBC của mình bằng cách gọi phương thức Class.forName. Các phương thức này yêu cầu một đối tượng kiểu java.sql.Driver. Mỗi trình điều khiển JDBC chứa một hoặc nhiều lớp thực hiện giao diện java.sql.Driver.
...
Mọi trình điều khiển JDBC 4.0 được tìm thấy trong đường dẫn lớp của bạn đều được tải tự động. (Tuy nhiên, bạn phải tải thủ công bất kỳ trình điều khiển nào trước JDBC 4.0 bằng phương pháp này Class.forName.)

Đọc thêm (đọc: câu hỏi này là trùng lặp)


29
Nói cách khác, nó cho phép bạn sử dụng lớp Trình điều khiển mà không cần nhập rõ ràng cho lớp của bạn. Điều này cho phép bạn xây dựng dự án mà không cần phải có trình điều khiển Oracle trong classpath của bạn.
JustinKSU

3
nên lưu ý rằng mặc dù trong "di sản cách" bạn sẽ gọi Class.forName()mà không chiếm được tham chiếu đến driverClass trở, vì vậy nó có vẻ ở cái nhìn đầu tiên như một hoạt động không-op
matt b

11
Đó là bởi vì trình điều khiển JDBC nên có một trình khởi tạo tĩnh đăng ký trình điều khiển với DriverManager. Khi sử dụng Class.forName (), trình khởi tạo này được thực thi và trình điều khiển được đăng ký. Kể từ JDBC 4.0, bản thân DriverManager sử dụng ServiceLoader để tìm trình điều khiển trên classpath.
Mark Rotteveel

1
@MattBall, Về trước JDBC 4.0, việc lấy tham chiếu đến trình điều khiển hoặc gọi một hàm tĩnh của lớp trình điều khiển đó sẽ tự động tải lớp trình điều khiển. Vậy tại sao chúng ta phải làm thủ công Class.forName("etc.driver")?
Pacerier

1
@Pacerier giả định không chính xác. JDBC không biết bạn muốn tải trình điều khiển nào, vì vậy không có gì trong JDBC (là trình điều khiển bất khả tri) biết để tham chiếu đến lớp trình điều khiển. Vì vậy, bạn cần một cái gì đó kích hoạt tải lớp. Tôi cho rằng một phương thức tĩnh sẽ hoạt động thay vì Class.forName(...).
Matt Ball

13

Nó đăng ký trình điều khiển; một cái gì đó có dạng:

public class SomeDriver implements Driver {
  static {
    try {
      DriverManager.registerDriver(new SomeDriver());
    } catch (SQLException e) {
      // TODO Auto-generated catch block
    }
  }

  //etc: implemented methods
}

6

Từ hướng dẫn Java JDBC :

Trong các phiên bản trước của JDBC, để có được kết nối, trước tiên bạn phải khởi tạo trình điều khiển JDBC của mình bằng cách gọi phương thức Class.forName. Bất kỳ trình điều khiển JDBC 4.0 nào được tìm thấy trong đường dẫn lớp của bạn đều được tải tự động. (Tuy nhiên, bạn phải tải thủ công bất kỳ trình điều khiển nào trước JDBC 4.0 bằng phương pháp này Class.forName.)

Vì vậy, nếu bạn đang sử dụng trình điều khiển Oracle 11g (11.1) với Java 1.6, bạn không cần gọi Class.forName. Nếu không, bạn cần gọi nó để khởi tạo trình điều khiển.


1
@Jonathan bạn có nghĩa là gì khi "tải thủ công bất kỳ trình điều khiển nào trước JDBC 4.0 với phương thức Class.forName", bạn có thể vui lòng giải thích không?
Aravind

Lời Class.forNamegọi buộc trình nạp lớp tải lớp đã cho. Đây là bước tải thủ công được mô tả trong hướng dẫn.
Jonathan

@ Jonathan Vì vậy, đó là lý do tại sao kết nối của tôi vẫn làm việc mà không class.forName();:)
Asif Mushtaq

2

Trước Java 6, DriverManagerlớp sẽ không biết trình điều khiển JDBC nào bạn muốn sử dụng. Class.forName("...")là một cách để tải trước các lớp trình điều khiển.

Nếu bạn đang sử dụng Java 6, bạn không cần phải làm điều này nữa.


Có, một người cần sử dụng: OracleDataSource hiện docs.oracle.com/cd/B28359_01/java.111/b31224/urls.htm#i1070726 và nó tự tạo url: final OracleDataSource ds = new OracleDataSource (); ds.setDriverType ("mỏng"); ds.setServerName (tên máy chủ); ds.setPortNumber (cổng); //ds.setDatabaseName(dbName); ds.setServiceName (dbName); kết nối = ds.getConnection (người dùng, pwd);
Rajesh Goel

1

Lệnh này tải lớp trình điều khiển jdbc của Oracle để có sẵn cho phiên bản DriverManager. Sau khi lớp được tải hệ thống có thể kết nối với Oracle bằng cách sử dụng nó. Thay vào đó, bạn có thể sử dụng phương thức registerDriver của DriverManager và chuyển nó với phiên bản trình điều khiển JDBC mà bạn cần.



0

Sử dụng oracle.jdbc.OracleDriver, không phải oracle.jdbc.driver.OracleDriver. Bạn không cần phải đăng ký nó nếu tệp jar trình điều khiển nằm trong thư mục "WEB-INF \ lib", nếu bạn đang sử dụng Tomcat. Lưu tệp này dưới dạng test.jsp và đặt nó vào thư mục web của bạn và triển khai lại thư mục ứng dụng web của bạn trong trình quản lý Tomcat:

<%@ page import="java.sql.*" %>

<HTML>
<HEAD>
<TITLE>Simple JSP Oracle Test</TITLE>
</HEAD><BODY>
<%
Connection conn = null;
try {
    Class.forName("oracle.jdbc.OracleDriver");
    conn = DriverManager.getConnection("jdbc:oracle:thin:@XXX.XXX.XXX.XXX:XXXX:dbName", "user", "password");
    Statement stmt = conn.createStatement();
    out.println("Connection established!");
}
catch (Exception ex)
{
    out.println("Exception: " + ex.getMessage() + "");

}
finally
{
    if (conn != null) {
        try {
            conn.close();   
        }
        catch (Exception ignored) {
            // ignore
        }
    }
}

%>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.