首页 > 解决方案 > Javafx 表加载正确的行数,但加载重复数据。我错过了什么吗?

问题描述

我的代码应该通过该方法loadCusotmerTable()使用 JDBC 从 MYSQL 数据库加载 javafx 中的客户表视图。CustomerDOA.findAll()findAll()方法返回应显示客户的 ObservableList。

Table 输出当前显示 Observable 列表中每个客户的正确行数,但它只显示 ObservableList 中最后一个条目的数据。我的代码中是否缺少ObservableList<Customer> Customers正确加载的内容?

加载客户表

package Controller;

import Model.Customer;
import Model.DAO.CustomerDAO;
import Model.DAO.UserDAO;
import Model.DBConnection;
import java.io.IOException;
import java.net.URL;
import java.sql.Connection;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.util.HashSet;
import java.util.ResourceBundle;
import java.util.Set;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.MenuButton;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.stage.Stage;

public class CustomerViewController implements Initializable {
    
    @FXML private TextField TextFieldCustomerID;
    @FXML private TextField TextFieldCustomerName;
    
    @FXML private Button ButtonGoBack;
    @FXML private Button ButtonAddModify;
    @FXML private Button ButtonRemove;
    @FXML private Button ButtonCancel;
    
    @FXML private MenuButton MenuButtonAddress;
    
    @FXML private MenuButton MenuButtonActive;
    @FXML private MenuItem MenuActiveItemActive;
    @FXML private MenuItem MenuActiveItemInactive;
    
    @FXML private TableView<Customer> TableViewCustomer;
    @FXML private TableColumn<Customer, String> TableCustomerColumnCustomerID;
    @FXML private TableColumn<Customer, String> TableCustomerColumnCustomerName;
    @FXML private TableColumn<Customer, String> TableCustomerColumnAddress;
    @FXML private TableColumn<Customer, String> TableCustomerColumnActive;
    
    private int addressId = 1;
    private int Active = 1;
    private int userId = 1;
    
    private boolean isCustomerSelected = true;
    private ObservableList<Customer> Customers = FXCollections.observableArrayList();

    // .......

    public void loadCustomerTable(){
        
        CustomerDAO customerDAO = new CustomerDAO(DBConnection.getConnection());        
        ObservableList<Customer> Customers = customerDAO.findAll();
       
        TableCustomerColumnCustomerID.setCellValueFactory(new PropertyValueFactory<>("customerId"));
        TableCustomerColumnCustomerName.setCellValueFactory(new PropertyValueFactory<>("customerName"));
        TableCustomerColumnAddress.setCellValueFactory(new PropertyValueFactory<>("addressId"));
        TableCustomerColumnActive.setCellValueFactory(new PropertyValueFactory<>("active"));
        
        TableViewCustomer.setItems(Customers);
    }

CustomerDAO.findAll()

 public ObservableList<Customer> findAll() {
        ObservableList<Customer> Customers = FXCollections.observableArrayList();
        Customer customer = new Customer();
        
        try(PreparedStatement statement = this.connection.prepareStatement(GET_ALL)){

            ResultSet resultSet = statement.executeQuery();
            int i =0;
            while(resultSet.next()){
                
                customer.setCustomerId(resultSet.getInt("customerId"));
                customer.setCustomerName(resultSet.getString("customerName"));
                customer.setAddressId(resultSet.getInt("addressId"));
                customer.setActive(resultSet.getInt("active"));
                customer.setCreateDate(resultSet.getTimestamp("createDate"));
                customer.setLastUpdate(resultSet.getTimestamp("lastUpdate"));
                customer.setCreatedBy(resultSet.getString("createdBy"));
                customer.setLastUpdateBy(resultSet.getString("lastUpdateBy"));
                
                Customers.add(customer);
                System.out.println(Customers.get(i).getCustomerName());
                i++;
            }
            
        }catch(SQLException e){
            e.printStackTrace();
            throw new RuntimeException(e);
        }
         
        return Customers;
    }

客户类

import Utils.DataTransferObject;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.Date;
import javafx.beans.property.IntegerProperty;


public class Customer implements DataTransferObject {
    private int customerId;
    private String customerName; //varchar 45
    private int addressId;
    private int active; // tiny int 1
    private LocalDateTime createDate;
    private LocalDateTime  lastUpdate;
    private String createdBy;
    private String lastUpdateBy;
    
    @Override
    public long getId() {
        return customerId;
    }
    
    public int getCustomerId() {
        return customerId;
    }
    

    public void setCustomerId(int customerId) {
        this.customerId = customerId;
    }

    public String getCustomerName() {
        return customerName;
    }

    public void setCustomerName(String customerName) {
        this.customerName = customerName;
    }

    public int getAddressId() {
        return addressId;
    }

    public void setAddressId(int addressId) {
        this.addressId = addressId;
    }

    public int getActive() {
        return active;
    }

    public void setActive(int active) {
        this.active = active;
    }

    public LocalDateTime getCreateDate() {
        return createDate;
    }

    public void setCreateDate(LocalDateTime createDate) {
        this.createDate = createDate;
    }
    
    public void setCreateDate(Timestamp createDate) {
        
        this.createDate = createDate.toLocalDateTime();
        
    }

    public LocalDateTime getLastUpdate() {
        return lastUpdate;
    }

    public void setLastUpdate(LocalDateTime lastUpdate) {
        this.lastUpdate = lastUpdate;
    }
    
    public void setLastUpdate(Timestamp lastUpdate) {
        this.lastUpdate = lastUpdate.toLocalDateTime();
    }
    
    public String getCreatedBy() {
        return createdBy;
    }

    public void setCreatedBy(String createdBy) {
        this.createdBy = createdBy;
    }

    public String getLastUpdateBy() {
        return lastUpdateBy;
    }

    public void setLastUpdateBy(String lastUpdateBy) {
        this.lastUpdateBy = lastUpdateBy;
    }

}

在此处输入图像描述

标签: javamysqljavafx

解决方案


您的CustomerDAO.findAll()方法重复地将相同的Customer实例添加到表中(每次都更改该单个对象中的数据)。因此,该表包含对同一对象的多个引用。

内存图片如下所示:

显示三个引用列表的内存堆卡通,每个引用都引用同一个 Customer 实例

由于只有一个Customer对象,因此只有一个customerId、一个customerName等,并且列表的每个元素都引用相同的值。

Customer相反,每次都创建一个新的,并将其添加到列表中。那么内存图片是这样的:

内存堆卡通,显示三个引用的列表,每个引用指向不同的客户实例

public ObservableList<Customer> findAll() {
    ObservableList<Customer> customers = FXCollections.observableArrayList();

    try(PreparedStatement statement = this.connection.prepareStatement(GET_ALL)){

        ResultSet resultSet = statement.executeQuery();
        int i =0;
        while(resultSet.next()){

            // This line moved inside the loop, to create a new
            // object on each iteration:
            Customer customer = new Customer();

            customer.setCustomerId(resultSet.getInt("customerId"));
            customer.setCustomerName(resultSet.getString("customerName"));
            customer.setAddressId(resultSet.getInt("addressId"));
            customer.setActive(resultSet.getInt("active"));
            customer.setCreateDate(resultSet.getTimestamp("createDate"));
            customer.setLastUpdate(resultSet.getTimestamp("lastUpdate"));
            customer.setCreatedBy(resultSet.getString("createdBy"));
            customer.setLastUpdateBy(resultSet.getString("lastUpdateBy"));

            customers.add(customer);
            System.out.println(customers.get(i).getCustomerName());
            i++;
        }

    }catch(SQLException e){
        e.printStackTrace();
        throw new RuntimeException(e);
    }

    return customers;
}

推荐阅读