更新和删除不适用于使用 JAVAFx 的 mysql 数据库

Posted

技术标签:

【中文标题】更新和删除不适用于使用 JAVAFx 的 mysql 数据库【英文标题】:Update and Delete doesnt work with mysql database using JAVAFx 【发布时间】:2020-03-25 21:11:56 【问题描述】:

问题:我正在尝试创建车辆预订系统,当用户预订显示在表格视图上的特定车辆并按车牌号删除时,我想显示 数据库 的更新. 我已经仔细检查了查询,但它不能通过代码工作,也不能在 phpmyadmin sql 中工作。代码如下所示:

public class PrintCar extends Application implements Initializable 

    public TableColumn col_plateNum;
    public TableColumn col_air;
    public TableColumn col_seats;
    public TableColumn col_make;
    public TableColumn col_miles;
    public TableColumn col_year;
    public TableColumn col_price;
    public TableColumn col_color;
    public TableView table;
    public TextField plateNum;
    public DatePicker dateReserved;
    public TableColumn col_ID;
    public TableColumn col_reservedDate;
    public TableColumn col_reserved;
    ResultSet rs;


    @Override
    public void start(Stage stage) throws Exception 
        Parent root= FXMLLoader.load(getClass().getResource("../GUI/PrintCar.fxml"));
        stage.setTitle("JavaFX 2 Login");
        stage.setScene(new Scene(root, 327,700));
        stage.show();



    

    ObservableList<Vehicle> obList = FXCollections.observableArrayList();

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) 

        ConnectionClass connectionClass=new ConnectionClass();
        Connection connection=connectionClass.getConnection();
        PreparedStatement ps;

        try 
            ps = connection.prepareStatement("select * from cars ");
            rs = ps.executeQuery();
            obList.clear();
            while(rs.next())
                obList.add(new Car(rs.getString(1),rs.getString(2),
                        rs.getString(3), rs.getString(4), rs.getString(5)
                ,rs.getString(6), rs.getString(7), rs.getString(8), rs.getString(9), rs.getString(10), rs.getString(11)));

            
         catch (SQLException e) 
            e.printStackTrace();
        
        col_ID.setCellValueFactory(new PropertyValueFactory<>("ID"));
        col_plateNum.setCellValueFactory(new PropertyValueFactory<>("plateNumber"));
        col_color.setCellValueFactory(new PropertyValueFactory<>("Color"));
        col_price.setCellValueFactory(new PropertyValueFactory<>("pricePerKilometer"));
        col_year.setCellValueFactory(new PropertyValueFactory<>("year"));
        col_miles.setCellValueFactory(new PropertyValueFactory<>("milesTravelled"));
        col_make.setCellValueFactory(new PropertyValueFactory<>("make"));
        col_seats.setCellValueFactory(new PropertyValueFactory<>("maxPassengers"));
        col_air.setCellValueFactory(new PropertyValueFactory<>("airConditioned"));
        col_reserved.setCellValueFactory(new PropertyValueFactory<>("reserved"));
        col_reservedDate.setCellValueFactory(new PropertyValueFactory<>("reservedDate"));



        table.setItems(obList);
        table.getSortOrder().add(col_ID);
        table.getSortOrder().add(col_miles);
        table.getSortOrder().add(col_make);
        table.getSortOrder().add(col_reservedDate);


    

    public void reserveCar(ActionEvent actionEvent) throws SQLException 

        ConnectionClass connectionClass=new ConnectionClass();
        Connection connection=connectionClass.getConnection();
        PreparedStatement ps;
        PreparedStatement ps1;
        String mainSQL="SET SQL_SAFE_UPDATES = 0;";
        String sql = "UPDATE `cars` SET `Reserved`= ? ,`Reserved Date`= ? WHERE 'ID' = '"+plateNum.getText()+"'";

        try 
            ps1 = connection.prepareStatement(mainSQL);
            ps = connection.prepareStatement(sql);
            ps.setString(1, "Yes");
            ps.setString(2, dateReserved.getValue().toString());
            ps1.executeQuery();
            ps.executeUpdate();
         catch (SQLException e) 
            e.printStackTrace();
        

        Alert alert = new Alert(Alert.AlertType.INFORMATION);
        alert.setTitle("Database Confirmation");
        alert.setHeaderText("Success!");
        alert.setContentText("Data Successfully added to Database");
        alert.showAndWait();

        plateNum.setText("");
        dateReserved.setValue(null);
    

    public void deleteCar(ActionEvent actionEvent) 
        ConnectionClass connectionClass=new ConnectionClass();
        Connection connection=connectionClass.getConnection();
        PreparedStatement ps;
        String sql = "DELETE FROM `cars` WHERE 'Plate Number' = '"+plateNum.getText()+"'";

        try 
            ps = connection.prepareStatement(sql);
            ps.executeUpdate();
         catch (SQLException e) 
            e.printStackTrace();
        

        Alert alert = new Alert(Alert.AlertType.INFORMATION);
        alert.setTitle("Database Confirmation");
        alert.setHeaderText("Success!");
        alert.setContentText("Data Successfully added to Database");
        alert.showAndWait();

        plateNum.setText("");
        dateReserved.setValue(null);

    

【问题讨论】:

无关:见What is a raw type and why shouldn't we use it?。 我很确定 ' 包围的字符不被视为列,而是作为字符串文字。因此,如果plateNum 的文本包含Plate Number,则您的比较匹配所有行,否则不匹配。此外,为什么你的一半代码利用PreparedStatement 可以正确引用字符串而另一半不能。 【参考方案1】:

mysql 中,使用 '(单引号)字符来指定 SQL 查询谓词中的列名,被解释为字符串而不是数据库表列。 `(反引号)字符分隔标识符。

所以这样的查询:

SELECT * from cars WHERE 'Plate Number' = 'ABC' 

从不返回任何行,除非您要比较的字符串是“车牌号”本身:

SELECT * from cars WHERE 'Plate Number' = 'Plate Number'

在这种情况下,它会给出表的整个行集。 所以写查询的正确方法是:

SELECT * from cars WHERE `Plate Number` = 'ABC'

即使用 **** (backtick) character. In your case inreserveCar` 必须以这种方式指定查询:

String sql = "UPDATE `cars` SET `Reserved`= ? ,`Reserved Date`= ? WHERE `ID` = '"+plateNum.getText()+"'";

deleteCar 方法中:

String sql = "DELETE FROM `cars` WHERE 'Plate Number' = '"+plateNum.getText()+"'";

另一个需要注意的重要事项是,为了防止 SQL 注入等安全问题,最好使用PreparedStatement,强制将用户输入作为参数的内容处理,而不是作为 SQL 命令的一部分。因此,例如,最好将deleteCar 方法修改如下:

public void deleteCar(ActionEvent actionEvent) 
     ConnectionClass connectionClass=new ConnectionClass();
     Connection connection=connectionClass.getConnection();
     PreparedStatement ps;
     String sql = "DELETE FROM `cars` WHERE `Plate Number` = ? ";

     try 
         ps = connection.prepareStatement(sql);
         stmt.setString(1, plateNum.getText());
         ps.executeUpdate();
      catch (SQLException e) 
         e.printStackTrace();
     

     Alert alert = new Alert(Alert.AlertType.INFORMATION);
     alert.setTitle("Database Confirmation");
     alert.setHeaderText("Success!");
     alert.setContentText("Data Successfully added to Database");
     alert.showAndWait();

     plateNum.setText("");
     dateReserved.setValue(null);

【讨论】:

以上是关于更新和删除不适用于使用 JAVAFx 的 mysql 数据库的主要内容,如果未能解决你的问题,请参考以下文章

使用CheckBoxListCell的Javafx listview不适用于拖放

setWrapText(true)不适用于JavaFX中的Label

contentobserver 仅适用于插入和删除,但不适用于更新

Databricks 更新表不适用于 orc 格式

Kafka Connect with MSSQL 不适用于删除操作

如何一次更新所有JavaFX元素?