数据库连接上的sqlexception:没有找到适合JDBC的驱动程序:mysql:// localhost:3306/smtbiz
问题:我正在尝试创建一个用于运行我的JDBC应用程序的自我包含的文件,该文件与使用Javafx创建的前端连接。从IDE(NetBeans)运行该程序时,该程序可以很好地工作,但是在尝试使用我自己的批处理文件运行应用程序时;编译,创建自定义JRE,创建一个自定义JAR和启动我遇到此错误:
数据库连接上的SQLEXCEPTION:在JDBC上找不到合适的驱动程序:mysql:// localhost:3306/smtbiz
sqlstate:08001
解决方案解决方案:< /strong>在项目库中包括MySQL-connect.jar,并将其包括在编译时类路径位置。我已经很好地看了现有帖子。帮助非常感谢。
主要类
public class CustomerManagementGUI extends Application {
@Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("CustomerManagementUI.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
//launch(args);
Scanner sc = new Scanner(System.in);
CustomerManagementGUI.launch(args);
CreateDatabase.createCustomerDB();
}
数据库实用功能类
public class DBUtil {
private static final String URL_DB = "jdbc:mysql://localhost:3306/smtbiz";
private static final String USER = "root";
private static final String PASSWORD = "";
private static Connection con = null;
public static void connectDatabase() {
try {
con = DriverManager.getConnection(URL_DB, USER, PASSWORD);
con.setAutoCommit(false);
} catch (SQLException ex) {
System.out.println("SQLException on database connection: " + ex.getMessage());
System.out.println("SQLState: " + ex.getSQLState());
System.out.println("VendorError: " + ex.getErrorCode());
}
}
public static void closeDatabase() {
try {
if (con != null && !con.isClosed()) {
con.close();
}
} catch (SQLException ex) {
System.out.println("SQLException on database close: " + ex.getMessage());
}
}
public static ResultSet executeQuery(String queryStmt) {
Statement stmt = null;
ResultSet resultSet = null;
CachedRowSet crs = null;
try {
connectDatabase();
stmt = con.createStatement();
resultSet = stmt.executeQuery(queryStmt);
crs = RowSetProvider.newFactory().createCachedRowSet();
crs.populate(resultSet);
} catch (SQLException ex) {
System.out.println("SQLException on executeQuery: " + ex.getMessage());
} finally {
try {
if (resultSet != null) {
resultSet.close();
}
if (stmt != null) {
stmt.close();
}
closeDatabase();
} catch (SQLException ex) {
System.out.println("SQLException caught on database closing: " + ex.getMessage());
}
}
return crs;
}
public static int executeUpdate(String sqlStmt) {
Statement stmt = null;
int count;
try {
connectDatabase();
stmt = con.createStatement();
count = stmt.executeUpdate(sqlStmt);
con.commit();
return count;
} catch (SQLException ex) {
System.out.println("SQLException on executeUpdate: " + ex.getMessage());
return 0;
} finally {
try {
if (stmt != null) {
stmt.close();
}
closeDatabase();
} catch (SQLException ex) {
System.out.println("SQLException caught on database closing: " + ex.getMessage());
}
}
}
dao
public class CustomerDAO {
public static void insertCustomer(String name, String email, String mobile) {
String insertSQL = String.format("INSERT INTO customer (Name, Email, Mobile) VALUES ('%s', '%s', '%s');",
name, email, mobile);
int count = DBUtil.executeUpdate(insertSQL);
if (count == 0) {
System.out.println("Failed to add new customer.");
} else {
System.out.println("\nNew customer added successfully.");
}
}
public static void deleteCustomer(int customerID) {
String deleteSQL = "DELETE FROM customer WHERE id='" + customerID + "';";
int count = DBUtil.executeUpdate(deleteSQL);
if (count == 0) {
System.out.println("ID not found, delete unsuccessful.");
} else {
System.out.println("\nID successfully deleted.");
}
}
public static void editCustomer(int customerID, String customerName, String customerEmail, String customerMobile) {
String editCustomer = "UPDATE customer "
+ "SET name = " + "\"" + customerName + "\", " + "email = " + "\"" + customerEmail + "\", " + "mobile = " + "\"" + customerMobile + "\" "
+ "WHERE ID = " + "" + customerID + ";";
int count = DBUtil.executeUpdate(editCustomer);
if (count == 0) {
System.out.println("ID not found, edit unsuccessful.");
} else {
System.out.println("\nID successfully edited.");
}
}
public static Customer searchCustomerID(int id) throws SQLException {
String query = "SELECT * FROM customer WHERE ID =" + id + ";";
Customer c = null;
try {
ResultSet rs = DBUtil.executeQuery(query);
if (rs.next()) {
System.out.println("\nCustomer found: ");
c = new Customer();
c.setId(rs.getInt("ID"));
c.setName(rs.getString("Name"));
c.setEmail(rs.getString("Email"));
c.setMobile(rs.getString("Mobile"));
} else if (c == null){
System.out.println("Unfortunately that customer ID: " + id + " was not found.");
}
else {
System.out.println("Unfortunately that customer ID: " + id + " was not found.");
}
} catch (SQLException ex) {
System.out.println("SQLException on executeQuery: " + ex.getMessage());
}
return c;
}
public static ObservableList<Customer> getAllCustomers() throws ClassNotFoundException, SQLException {
String query = "SELECT * FROM customer;";
try {
ResultSet rs = DBUtil.executeQuery(query);
ObservableList<Customer> customerDetails = getCustomerModelObjects(rs);
return customerDetails;
} catch (SQLException ex) {
System.out.println("Error!");
ex.printStackTrace();;
throw ex;
}
}
public static ObservableList<Customer> getCustomerModelObjects(ResultSet rs) throws SQLException, ClassNotFoundException {
try {
ObservableList<Customer> customerList = FXCollections.observableArrayList();
while (rs.next()) {
Customer customer = new Customer();
customer.setId(rs.getInt("ID"));
customer.setName(rs.getString("Name"));
customer.setEmail(rs.getString("Email"));
customer.setMobile(rs.getString("Mobile"));
customerList.add(customer);
}
return customerList;
} catch (SQLException ex) {
throw ex;
}
}
类 不包括:节省后空间。
创建数据库类
public class CreateDatabase {
public static void createCustomerDB() {
String url = "jdbc:mysql://localhost:3306/"; // no database yet
String user = "root";
String password = "";
Connection con = null;
Statement stmt = null;
String query;
ResultSet result = null;
try {
con = DriverManager.getConnection(url, user, password);
stmt = con.createStatement();
query = "DROP DATABASE IF EXISTS smtbiz;";
stmt.executeUpdate(query);
query = "CREATE DATABASE smtbiz;";
stmt.executeUpdate(query);
query = "USE smtbiz;";
stmt.executeUpdate(query);
query = """
CREATE TABLE customer (
ID INTEGER NOT NULL AUTO_INCREMENT,
Name VARCHAR(32),
Email VARCHAR(25),
Mobile VARCHAR(15),
PRIMARY KEY(ID)
);
""";
stmt.executeUpdate(query);
query = """
INSERT INTO customer
(Name,Email,Mobile)
VALUES
("Kyle","[email protected]","0489358318"),
("John","[email protected]","0460358348"),
("Liam","[email protected]","0417335874"),
("Argon","[email protected]","0422358320"),
("Kris","[email protected]","0494358923");
""";
stmt.executeUpdate(query);
query = "SELECT * FROM customer;";
result = stmt.executeQuery(query); // execute the SQL query
} catch (SQLException ex) {
System.out.println("SQLException on database creation: " + ex.getMessage());
} finally {
try {
if (result != null) {
result.close();
}
if (stmt != null) {
stmt.close();
}
if (con != null) {
con.close();
}
} catch (SQLException ex) {
System.out.println("SQLException caught: " + ex.getMessage());
}
}
}
下面我包括了使用的批处理文件:
编译批处理
@echo off
javac --module-path %PATH_TO_FX% --add-modules=javafx.base,javafx.controls,javafx.fxml,javafx.graphics src\customermanagementgui\*.java -d classes
copy src\customermanagementgui\*.fxml classes\customermanagementgui\*.fxml
pause
创建jar batch
@echo off
md app
jar --create --file=app/CustomerManagementGUI.jar --main-class=customermanagementgui.CustomerManagementGUI -m Manifest.mf -C classes .
REM md app\lib
REM copy lib\mysql-connector-java.jar app\lib
xcopy .\lib\ .\app\lib /E /I
pause
创建jre批次
@echo off
jdeps -s --module-path %PATH_TO_FX% app\CustomerManagementGUI.jar
jlink --module-path ../jmods;%PATH_TO_FX_JMOD% --add-modules java.base,java.sql,java.sql.rowset,javafx.base,javafx.controls,javafx.fxml,javafx.graphics --output jre
echo ############
echo # Finished #
echo ############
pause
启动应用程序批次
@echo off
REM java -classpath classes customermanagementgui.CustomerManagementGUI
jre\bin\java -jar app/CustomerManagementGUI.jar
pause
Problem: I am trying to create a self contained file for running my JDBC application which interfaces with a front end created using javafx. The program works perfectly fine when running it from the IDE (NetBeans) however when trying to run the application utilising my own batch files for; compiling, creating a custom JRE, creating a custom JAR and launch I run into this error:
SQLException on database connection: No suitable driver found for jdbc:mysql://localhost:3306/smtbiz
SQLState: 08001
Solutions tried: including the mysql-connect.jar in the project library and including it in the compile time classpath location. I have had a good look at existing posts. Help is much much appreciated.
Main class
public class CustomerManagementGUI extends Application {
@Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("CustomerManagementUI.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
//launch(args);
Scanner sc = new Scanner(System.in);
CustomerManagementGUI.launch(args);
CreateDatabase.createCustomerDB();
}
Database utility function class
public class DBUtil {
private static final String URL_DB = "jdbc:mysql://localhost:3306/smtbiz";
private static final String USER = "root";
private static final String PASSWORD = "";
private static Connection con = null;
public static void connectDatabase() {
try {
con = DriverManager.getConnection(URL_DB, USER, PASSWORD);
con.setAutoCommit(false);
} catch (SQLException ex) {
System.out.println("SQLException on database connection: " + ex.getMessage());
System.out.println("SQLState: " + ex.getSQLState());
System.out.println("VendorError: " + ex.getErrorCode());
}
}
public static void closeDatabase() {
try {
if (con != null && !con.isClosed()) {
con.close();
}
} catch (SQLException ex) {
System.out.println("SQLException on database close: " + ex.getMessage());
}
}
public static ResultSet executeQuery(String queryStmt) {
Statement stmt = null;
ResultSet resultSet = null;
CachedRowSet crs = null;
try {
connectDatabase();
stmt = con.createStatement();
resultSet = stmt.executeQuery(queryStmt);
crs = RowSetProvider.newFactory().createCachedRowSet();
crs.populate(resultSet);
} catch (SQLException ex) {
System.out.println("SQLException on executeQuery: " + ex.getMessage());
} finally {
try {
if (resultSet != null) {
resultSet.close();
}
if (stmt != null) {
stmt.close();
}
closeDatabase();
} catch (SQLException ex) {
System.out.println("SQLException caught on database closing: " + ex.getMessage());
}
}
return crs;
}
public static int executeUpdate(String sqlStmt) {
Statement stmt = null;
int count;
try {
connectDatabase();
stmt = con.createStatement();
count = stmt.executeUpdate(sqlStmt);
con.commit();
return count;
} catch (SQLException ex) {
System.out.println("SQLException on executeUpdate: " + ex.getMessage());
return 0;
} finally {
try {
if (stmt != null) {
stmt.close();
}
closeDatabase();
} catch (SQLException ex) {
System.out.println("SQLException caught on database closing: " + ex.getMessage());
}
}
}
DAO Class
public class CustomerDAO {
public static void insertCustomer(String name, String email, String mobile) {
String insertSQL = String.format("INSERT INTO customer (Name, Email, Mobile) VALUES ('%s', '%s', '%s');",
name, email, mobile);
int count = DBUtil.executeUpdate(insertSQL);
if (count == 0) {
System.out.println("Failed to add new customer.");
} else {
System.out.println("\nNew customer added successfully.");
}
}
public static void deleteCustomer(int customerID) {
String deleteSQL = "DELETE FROM customer WHERE id='" + customerID + "';";
int count = DBUtil.executeUpdate(deleteSQL);
if (count == 0) {
System.out.println("ID not found, delete unsuccessful.");
} else {
System.out.println("\nID successfully deleted.");
}
}
public static void editCustomer(int customerID, String customerName, String customerEmail, String customerMobile) {
String editCustomer = "UPDATE customer "
+ "SET name = " + "\"" + customerName + "\", " + "email = " + "\"" + customerEmail + "\", " + "mobile = " + "\"" + customerMobile + "\" "
+ "WHERE ID = " + "" + customerID + ";";
int count = DBUtil.executeUpdate(editCustomer);
if (count == 0) {
System.out.println("ID not found, edit unsuccessful.");
} else {
System.out.println("\nID successfully edited.");
}
}
public static Customer searchCustomerID(int id) throws SQLException {
String query = "SELECT * FROM customer WHERE ID =" + id + ";";
Customer c = null;
try {
ResultSet rs = DBUtil.executeQuery(query);
if (rs.next()) {
System.out.println("\nCustomer found: ");
c = new Customer();
c.setId(rs.getInt("ID"));
c.setName(rs.getString("Name"));
c.setEmail(rs.getString("Email"));
c.setMobile(rs.getString("Mobile"));
} else if (c == null){
System.out.println("Unfortunately that customer ID: " + id + " was not found.");
}
else {
System.out.println("Unfortunately that customer ID: " + id + " was not found.");
}
} catch (SQLException ex) {
System.out.println("SQLException on executeQuery: " + ex.getMessage());
}
return c;
}
public static ObservableList<Customer> getAllCustomers() throws ClassNotFoundException, SQLException {
String query = "SELECT * FROM customer;";
try {
ResultSet rs = DBUtil.executeQuery(query);
ObservableList<Customer> customerDetails = getCustomerModelObjects(rs);
return customerDetails;
} catch (SQLException ex) {
System.out.println("Error!");
ex.printStackTrace();;
throw ex;
}
}
public static ObservableList<Customer> getCustomerModelObjects(ResultSet rs) throws SQLException, ClassNotFoundException {
try {
ObservableList<Customer> customerList = FXCollections.observableArrayList();
while (rs.next()) {
Customer customer = new Customer();
customer.setId(rs.getInt("ID"));
customer.setName(rs.getString("Name"));
customer.setEmail(rs.getString("Email"));
customer.setMobile(rs.getString("Mobile"));
customerList.add(customer);
}
return customerList;
} catch (SQLException ex) {
throw ex;
}
}
Customer Object Class
Not included: to save post space.
Create Database Class
public class CreateDatabase {
public static void createCustomerDB() {
String url = "jdbc:mysql://localhost:3306/"; // no database yet
String user = "root";
String password = "";
Connection con = null;
Statement stmt = null;
String query;
ResultSet result = null;
try {
con = DriverManager.getConnection(url, user, password);
stmt = con.createStatement();
query = "DROP DATABASE IF EXISTS smtbiz;";
stmt.executeUpdate(query);
query = "CREATE DATABASE smtbiz;";
stmt.executeUpdate(query);
query = "USE smtbiz;";
stmt.executeUpdate(query);
query = """
CREATE TABLE customer (
ID INTEGER NOT NULL AUTO_INCREMENT,
Name VARCHAR(32),
Email VARCHAR(25),
Mobile VARCHAR(15),
PRIMARY KEY(ID)
);
""";
stmt.executeUpdate(query);
query = """
INSERT INTO customer
(Name,Email,Mobile)
VALUES
("Kyle","[email protected]","0489358318"),
("John","[email protected]","0460358348"),
("Liam","[email protected]","0417335874"),
("Argon","[email protected]","0422358320"),
("Kris","[email protected]","0494358923");
""";
stmt.executeUpdate(query);
query = "SELECT * FROM customer;";
result = stmt.executeQuery(query); // execute the SQL query
} catch (SQLException ex) {
System.out.println("SQLException on database creation: " + ex.getMessage());
} finally {
try {
if (result != null) {
result.close();
}
if (stmt != null) {
stmt.close();
}
if (con != null) {
con.close();
}
} catch (SQLException ex) {
System.out.println("SQLException caught: " + ex.getMessage());
}
}
}
Below I have included the batch files used:
Compile Batch
@echo off
javac --module-path %PATH_TO_FX% --add-modules=javafx.base,javafx.controls,javafx.fxml,javafx.graphics src\customermanagementgui\*.java -d classes
copy src\customermanagementgui\*.fxml classes\customermanagementgui\*.fxml
pause
Create JAR batch
@echo off
md app
jar --create --file=app/CustomerManagementGUI.jar --main-class=customermanagementgui.CustomerManagementGUI -m Manifest.mf -C classes .
REM md app\lib
REM copy lib\mysql-connector-java.jar app\lib
xcopy .\lib\ .\app\lib /E /I
pause
Create JRE batch
@echo off
jdeps -s --module-path %PATH_TO_FX% app\CustomerManagementGUI.jar
jlink --module-path ../jmods;%PATH_TO_FX_JMOD% --add-modules java.base,java.sql,java.sql.rowset,javafx.base,javafx.controls,javafx.fxml,javafx.graphics --output jre
echo ############
echo # Finished #
echo ############
pause
Launch Application Batch
@echo off
REM java -classpath classes customermanagementgui.CustomerManagementGUI
jre\bin\java -jar app/CustomerManagementGUI.jar
pause
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
将所需的罐子放在classPath上
让我们假设您的图像中有一个
app
目录,遵循标准图像目录布局并将 the the mysql-connector-java jar和您的应用程序jar在该应用程序目录中(以及您的应用程序jar)您想从类路径运行的任何其他非模块化罐子)。然后,您可以执行以下操作:罐子此命令:
这将要做的是同时运行您的应用程序和MySQL连接器(将它们放在未命名的模块中)。 Java运行时和Javafx组件是模块化的,您已经将它们包装到了运行时映像中,因此您不需要任何其他模块参数。
该命令不使用
-jar
命令使用可执行JAR,为在阴影上
您可以通过将两个包装到同一目录中,然后重新包装来将MySQL Connector jar文件遮蔽到您的应用程序文件中。但是,在我看来,将应用程序毫无样式的命令行开关添加了无名模块的JARS,这似乎更好。
关于阴影jar的主要有用的内容是它是一个文件,并且具有简短的执行命令。但是您已经有很多文件,因为您拥有
jlink
图像。另外,您有一个批处理文件可以执行执行。因此,您不会从阴影罐(IMO)中获得任何好处。如果使用阴影,还需要注意不要在阴影jar中包含Javafx模块,因为在该执行模式下不支持它们。
附加信息
最好的事情就是将MySQL连接器模块(以及您定义的应用程序模块)链接到您正在创建的JLINK图像中。但是,当前,MySQL连接器并未定义模块-INFO文件,因此无法链接。如果放置在模块路径上,那么当前的MySQL连接器实现将变为自动模块。
如果您需要用于应用程序的安装程序,则应使用
jpackage
。有关包装Javafx应用程序的更多信息,请参见:
Placing required jars on the classpath
Let's assume that you have an
app
directory in your image which follows the standard image directory layout and have placed both the mysql-connector-java jar and your application jar in that app directory (as well as any additional non-modular jars which you want to run from the classpath). Then you can do the following:Change your launch application batch file to use this command:
What this will do is run both your app and the MySQL connector off of the classpath (placing them in the unnamed module). The Java runtime and JavaFX components are modular and you have already packed them into your runtime image, so you don't need any additional module arguments.
The command does not use an executable jar with the
-jar
command as that does not allow adding items outside of the jar command to the classpath:On Shading
You could shade the MySQL connector jar file into your application file by unpacking both into the same directory, then repacking them. But, it would seem better to me just to leave the app unshaded and use the classpath command-line switch to add jars for the unnamed module.
The primary useful things about a shaded jar are it is a single file and that it has a short execution command. But you already have lots of files because you have the
jlink
image. Also, you have a batch file to perform the execution. So you gain no benefit from a shaded jar (IMO).If shading is used, care also needs to be taken to not include JavaFX modules in the shaded jar, as they are not supported in that execution mode.
Additional Info
The nicest thing would be to just link a MySQL connector module (and an application module you define) into the jlink image you are creating. However, currently, the MySQL connector does not define a module-info file, so it is not linkable. If placed on the module path, the current MySQL connector implementation would become an automatic module.
If you need an installer for your application, then you should use
jpackage
.More information on packaging JavaFX applications can be found in: