MySQL Connector/J是否实现JdbcRowSet?JDK11使用遇驱动异常求助
JdbcRowSet抛出"No suitable driver found"异常的问题排查与解决
根据你描述的学习场景:你正在跟着Oracle Java Tutorials学习JDBC RowSet相关内容,用MySQL Server和最新版Connector/J(mysql-connector-java-8.0.16.jar)做测试,普通的数据库连接、ResultSet数据查询都能正常工作,但使用JdbcRowSet执行execute()时却抛出了No suitable driver found的SQL异常,你还疑惑是不是驱动未实现RowSet接口、自己操作有误,或是JDK11不再支持该功能。
问题分析
先帮你排除几个疑虑:
- Connector/J不需要实现RowSet接口:JdbcRowSet(包括CachedRowSet、JoinRowSet等)是JDK自带
javax.sql.rowset包下的接口,它的实现类(比如com.sun.rowset.JdbcRowSetImpl)是JDK提供的,MySQL驱动只需要完成基础JDBC驱动的实现就行,所以不是驱动的问题。 - 你的代码操作没有错误:从代码来看,连接URL、用户名密码、查询命令的设置都没问题,而且之前普通ResultSet能正常跑通,说明连接参数都是有效的。
从堆栈信息能看出,异常是在com.sun.rowset.JdbcRowSetImpl.connect方法调用DriverManager.getConnection时抛出的,这其实是JDK11.0.1的版本bug——JDK11模块化之后,RowSet实现的类加载环境下,DriverManager的驱动扫描机制无法找到已经注册的MySQL驱动。
解决方案
你已经发现升级到JDK12.0.1后问题消失,这确实是最直接有效的解决办法,因为JDK12修复了JDK11早期版本中RowSet相关的驱动加载问题。
如果暂时没法升级JDK,也可以试试这个临时 workaround:
- 在创建JdbcRowSet之前,手动注册MySQL驱动:
虽然JDBC4.0+支持自动注册驱动,但JDK11.0.1的类加载环境下,RowSet的实现可能扫不到驱动,手动注册能强制让DriverManager加载驱动类。Class.forName("com.mysql.cj.jdbc.Driver");
你的示例代码
import javax.sql.rowset.JdbcRowSet; import javax.sql.rowset.RowSetProvider; import java.sql.*; import java.util.Properties; public class JdbcRowSetTest { public static void main(String[] args) { String connectionURL = "jdbc:mysql://localhost:3306/testdb?serverTimezone=Europe/Moscow"; String userName = "root"; String password = "root"; try { Properties connectionProps = new Properties(); connectionProps.put("user", userName); connectionProps.put("password", password); System.out.println("Connect to database..."); Connection conn = DriverManager.getConnection(connectionURL, connectionProps); System.out.println("Retrieve and process data using ResultSet..."); Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("select * from COFFEES"); while (rs.next()) { String coffeeName = rs.getString("COF_NAME"); float price = rs.getFloat("PRICE"); System.out.println(coffeeName + ", " + price); } System.out.println("Now, update the data using JdbcRowSet..."); JdbcRowSet jdbcRs = RowSetProvider.newFactory().createJdbcRowSet(); jdbcRs.setUrl(connectionURL); jdbcRs.setUsername(userName); jdbcRs.setPassword(password); jdbcRs.setCommand("select * from COFFEES"); // it's where SQLException is thrown jdbcRs.execute(); jdbcRs.absolute(2); jdbcRs.updateFloat("PRICE", 10.99f); jdbcRs.updateRow(); System.out.println("After updating the 2nd row:"); //... view updated table } catch (SQLException e) { e.printStackTrace(); } } }
运行输出
Connect to database... Retrieve and process data using ResultSet... Colombian, 7.99 Espresso, 9.99 Now, update the data using ResultSet... java.sql.SQLException: No suitable driver found for jdbc:mysql://localhost:3306/testdb?serverTimezone=Europe/Moscow at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:702) at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:228) at java.sql.rowset/com.sun.rowset.JdbcRowSetImpl.connect(JdbcRowSetImpl.java:643) at java.sql.rowset/com.sun.rowset.JdbcRowSetImpl.prepare(JdbcRowSetImpl.java:654) at java.sql.rowset/com.sun.rowset.JdbcRowSetImpl.execute(JdbcRowSetImpl.java:556) at JdbcRowSetTest.main(JdbcRowSetTest.java:37)
内容的提问来源于stack exchange,提问作者escudero380
相关产品推荐
相关产品推荐

