数据库连接上的SQLException:找不到适用于jdbc的驱动程序:mysql://localhost:3306/s



问题:我正试图创建一个用于运行JDBC应用程序的自包含文件,该文件与使用javafx创建的前端接口。当从IDE(NetBeans)运行程序时,该程序运行得非常好,但当尝试使用我自己的批处理文件运行应用程序时;编译、创建自定义JRE、创建自定义JAR并启动时遇到以下错误:

数据库连接上的SQLException:找不到适用于jdbc的驱动程序:mysql://localhost:3306/smtbiz

SQL状态:08001

尝试过的解决方案:将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","Kyle.Henry@gmail.com","0489358318"),
("John","John.Potter@outlook.com","0460358348"),
("Liam","Liam.Stone@hotmail.com","0417335874"),
("Argon","Argon.Chung@gmail.com","0422358320"),
("Kris","Kris.Frank@gmail.com","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 srccustomermanagementgui*.java -d classes 
copy srccustomermanagementgui*.fxml classescustomermanagementgui*.fxml
pause

创建JAR批

@echo off
md app
jar --create --file=app/CustomerManagementGUI.jar --main-class=customermanagementgui.CustomerManagementGUI -m Manifest.mf -C classes .
REM md applib
REM copy libmysql-connector-java.jar applib
xcopy .lib .applib /E /I
pause

创建JRE批

@echo off
jdeps -s --module-path %PATH_TO_FX% appCustomerManagementGUI.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
jrebinjava -jar app/CustomerManagementGUI.jar
pause

将所需的jar放置在类路径上

假设您的映像中有一个app目录,该目录遵循标准映像目录布局,并已将mysql连接器javajar和您的应用程序jar(以及您希望从类路径运行的任何其他非模块化jar)都放置在该应用程序目录中。然后您可以执行以下操作:

  • 在Java类路径中的一个目录中包括所有jar

更改启动应用程序批处理文件以使用以下命令:

binjava -classpath app* customermanagementgui.CustomerManagementGUI

这样做的目的是在类路径之外运行应用程序和MySQL连接器(将它们放在未命名的模块中)。Java运行时和JavaFX组件是模块化的,您已经将它们打包到运行时映像中,因此不需要任何额外的模块参数。

该命令不将可执行jar与-jar命令一起使用,因为这不允许将jar命令之外的项添加到类路径:

当您使用-jar时,指定的jar文件是所有用户类的源,其他类路径设置将被忽略。

着色时

您可以将MySQL连接器jar文件屏蔽到您的应用程序文件中,方法是将两者拆包到同一目录中,然后重新打包。但是,对我来说,最好是让应用程序不受影响,并使用classpath命令行开关为未命名的模块添加jar。

着色jar的主要有用之处在于它是一个单独的文件,并且它有一个简短的执行命令。但是您已经有了很多文件,因为您有jlink映像。此外,您还有一个批处理文件来执行。因此,你不会从阴影罐子(IMO)中获得任何好处。

如果使用着色,还需要注意不要在着色jar中包含JavaFX模块,因为在该执行模式中不支持它们。

附加信息

最好的方法是将MySQL连接器模块(以及您定义的应用程序模块)链接到您正在创建的jlink映像中。但是,目前MySQL连接器没有定义模块信息文件,因此它是不可链接的。如果放在模块路径上,当前MySQL连接器实现将成为一个自动模块。

如果您的应用程序需要安装程序,那么您应该使用jpackage

有关打包JavaFX应用程序的更多信息,请访问:

  • javafx标记的打包部分

相关内容

  • 没有找到相关文章

最新更新