Javafx 表加载正确的行数,但加载重复的数据。我错过了什么吗?

标签 java mysql javafx

我的代码应该通过 loadCusotmerTable() 在 javafx 中加载客户 TableView 从 MYSQL 数据库通过 JDBC 通过 CustomerDOA.findAll()方法。 findAll()方法返回一个应显示客户的 ObservableList。

表输出当前显示 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;
    }

}

enter image description here

最佳答案

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

内存图片如下:

Cartoon of memory heap showing a list of three references, each referring to the same instance of Customer

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

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

Cartoon of memory heap, showing a list of three references, each to a different Customer instance

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;
}

关于Javafx 表加载正确的行数,但加载重复的数据。我错过了什么吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60242325/

相关文章:

java - 当我在 javafx.scene.control.TextArea 中按下 ALT ENTER 时如何禁用声音?

java - Selenium:无法使用 aShot 库获取完整的页面截图

java - 当我尝试从 play 框架访问我​​的数据库(MySQL)时,我在编码 :"The import play.db cannot be resolved"时收到此错误

java - Eclipse 4. 2 Java 控制台更改背景颜色

php - 划分mysql查询以适应div

php - mysql 和 php 中的限制查询之间的区别

javafx - 在 Raspberry Pi 上使用 JavaFX 播放视频

java - Javafx-在具有gradle错误的intelliJ上:包javafx.fxml不存在导入javafx.fxml.FXML

java - ZipEntry UTF-8 字符集

java - 为什么 javac 提示与类的类型参数无关的泛型?