Nước mắt và nỗi đau
Lỗi có thể xảy ra khi chạy chương trình Java. Khi làm việc với cơ sở dữ liệu sẽ xảy ra lỗi. Đó là tất cả những gì bạn có thể dự đoán và đưa ra một giải pháp thích hợp.
Nhóm lỗi lớn đầu tiên sẽ chờ bạn khi thực hiện dòng này:
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "secret");
Bạn có thể mong đợi điều gì ở đây?
Lỗi 1. Không tìm thấy trình điều khiển .
Nếu bạn gặp lỗi “Không tìm thấy trình điều khiển phù hợp cho…” , điều đó có nghĩa là Trình quản lý trình điều khiển không thể hiểu loại DBMS nào đằng sau URL của bạn. Ví dụ: bạn đã viết jdbc_mysql: thay vì jdbc:mysql:
Lỗi 2. Lỗi kết nối .
Nếu bạn nhập sai tên máy chủ, rất có thể bạn sẽ nhận được thông báo như “Không biết máy chủ nào như vậy” hoặc “Lỗi liên kết giao tiếp”.
Lỗi 3. Tên cơ sở dữ liệu không chính xác .
Nếu bạn viết sai tên cơ sở dữ liệu hoặc kết nối với một máy chủ khác không tồn tại, bạn sẽ nhận được thông báo như “Cơ sở dữ liệu không xác định 'supershop3'” .
Lỗi 4. Đăng nhập hoặc mật khẩu sai .
Nếu bạn quên mật khẩu cơ sở dữ liệu hoặc nhập sai mật khẩu, thì rất có thể bạn sẽ nhận được thông báo như “Quyền truy cập bị từ chối đối với người dùng 'root'@'localhost' (sử dụng mật khẩu: CÓ)” .
Ngoại lệ SQL
Nếu kết nối với cơ sở vẫn được thiết lập, thì nó sẽ còn thú vị hơn nữa. Trong trường hợp có lỗi khi làm việc với cơ sở dữ liệu, JDBC có một ngoại lệ đặc biệt - java.sql.SQLException . Cũng như một số giống của nó.
Ngoại lệ này chỉ có một phương thức bổ sung (so với lớp Ngoại lệ) - phương thức getSQLState(), trả về mã trạng thái (chuỗi) mà máy chủ SQL đã trả về cho nó. Xử lý lỗi trông như thế này:
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "secret");
try {
int rowsCount = statement.executeUpdate("DELETE FROM ‘Unemployees’");
} catch (SQLException ex) {
// If table doesn't exist
if (ex.getSQLState().compareTo("X0Y32") != 0) {
throw ex;
}
} finally {
connection.close();
}
Có hàng trăm mã lỗi. Bạn có thể xem danh sách đầy đủ tại đây .
Nhưng đôi khi các mã lỗi giúp JDBC hiểu lỗi tốt hơn và sau đó nó ném ra không chỉ SQLException, mà cả SQLException chuyên biệt:
BatchUpdateException | Lỗi trong khi yêu cầu nhóm |
Truncation dữ liệu | Thường xảy ra khi cắt bớt dữ liệu dài |
SQLClientInfoException | Máy khách đã chuyển các tham số không thể đặt trên kết nối: Kết nối |
SQLDataException | Lỗi với dữ liệu, chi tiết tùy thuộc vào loại DBMS |
SQLException | Lỗi truy cập cơ sở dữ liệu hoặc các lỗi chung khác |
SQLFeatureNotSupportedException | DBMS không hỗ trợ chức năng này |
SQLIntegrityConstraintViolationException | Tất cả các lỗi với SQLState ==22 |
SQLInvalidAuthorizationSpecException | Lỗi truy cập và/hoặc ủy quyền |
SQLNonTransientConnectionException | Tất cả các lỗi với SQLState ==08 |
SQLRecoverableException | Có một lỗi, nhưng nó có thể được sửa bằng sự can thiệp của ứng dụng |
SQLSyntaxErrorException | Lỗi trong cú pháp truy vấn |
SQLTimeoutException | Yêu cầu mất quá nhiều thời gian |
SQLTransactionRollbackException | Lỗi trong quá trình khôi phục giao dịch |
SQLCảnh báo | Cảnh báo do DBMS đưa ra |
Ví dụ về lỗi
Nếu một lỗi xảy ra ở giai đoạn của ứng dụng máy chủ, thì thông thường nó chỉ có thể được ghi lại và sau đó xử lý chi tiết hơn. Nhưng nếu nó xảy ra trong khi ứng dụng đang chạy trên máy tính của lập trình viên, thì bạn cần điều tra kỹ lý do của việc này.
Có hai loại lỗi lớn nhất khi làm việc với cơ sở dữ liệu:
- Lỗi văn bản yêu cầu
- Lỗi khi làm việc với ResultSet
Một lỗi trong văn bản yêu cầu có thể xảy ra rất thường xuyên. Truy vấn có thể rất dài, chứa nhiều bảng (được nối thông qua THAM GIA) và truy vấn con (SUBSELECT). Không dễ để tìm ra lỗi trong một yêu cầu như vậy. Ngoài ra, các yêu cầu thường được dán lại với nhau từ các bộ phận, dữ liệu được thêm vào đó.
Lỗi đầu tiên bạn nên biết là SQLSyntaxErrorException . Lỗi như vậy thường có nghĩa là bạn mắc lỗi đánh máy trong phần thân yêu cầu.
Hãy lấy ví dụ yêu thích của chúng tôi:
ResultSet results = statement.executeQuery("SELECT Count(*) FROM user");
results.next();
int count = results.getInt(1);
Và “vô tình” xóa dấu hoa thị trong phần thân yêu cầu:
ResultSet results = statement.executeQuery("SELECT Count() FROM user");
results.next();
int count = results.getInt(1);
Sau đó, chúng tôi sẽ nhận được một ngoại lệ:
Exception in thread "main" java.sql.SQLSyntaxErrorException:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ') FROM task' at line 1
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:120)
Máy chủ SQL cho chúng tôi biết rằng đã có lỗi cú pháp trước TỪ.
Chúng tôi cẩn thận xem xét yêu cầu và suy nghĩ. Nếu không có gì xuất hiện trong đầu và điều này xảy ra rất thường xuyên, thì bạn cần nhờ ai đó xem có gì sai.
Một lỗi phổ biến khác là làm việc không chính xác với ResultSet - kết quả của yêu cầu. Giả sử bạn quên rằng trước khi đọc dữ liệu, “hàng hiện tại” của đối tượng ResultSet đứng trước hàng đầu tiên, thì bạn sẽ có đoạn mã sau:
ResultSet results = statement.executeQuery("SELECT Count(*) FROM user");
// results.next();
int count = results.getInt(1);
Bạn sẽ nhận được lỗi này:
2012 12:55:48 AM jButton5ActionPerformed
SEVERE: null
java.sql.SQLException: Before start of result set
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1073)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:987)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:982)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:927)
at com.mysql.jdbc.ResultSetImpl.checkRowPos(ResultSetImpl.java:841)
at com.mysql.jdbc.ResultSetImpl.getStringInternal(ResultSetImpl.java:5650)
at com.mysql.jdbc.ResultSetImpl.getString(ResultSetImpl.java:5570)
Chúng tôi cẩn thận nhìn vào lỗi và suy nghĩ. Sau đó, chúng tôi google và tìm một vài ví dụ và cố gắng hiểu giải pháp.