• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Obsługa zapytań złożonych w Javie (Java FX)

VMware Cloud PRO - przenieś swoją infrastrukturę IT do chmury
0 głosów
537 wizyt
pytanie zadane 25 października 2017 w Java przez fusemul Użytkownik (710 p.)

Witam, mam pewnie dość prosty problem dla osoby siedzącej w temacie :) Ja niestety w Javie (a dokladniej w Javei FX) dopiero raczkuje, a potrzebuję napisać prostą aplikację.

Załóżmy, że mamy dwie tabele:
Sales:
ID, product_id, amount, price, date
Products:
ID, name, price

Cena jest i tu i tu, ponieważ w tabeli products będzie się ona zmieniać każdego dnia, a w tabeli Sales chcemy mieć zapisane jaka była cena dla konkretnej sprzedaży.

Jedna sprzedaż ma tylko jeden produkt (relacja 1 do 1). oczywiście sales.product_id = products.id.

Potrzeba jest banalna: za pomocą javy FX wyświetlić tabelę którą będzie populował następujący select:

select sale_id, name, amount, s.price, "date" from sales s, products p where s.product_id = p.product_id;

Moje pytanie jest następujące: Jak powinienem zbudować klasy w Modelu?

Czy w klasie Sales, product_id powinien być jako Long, czy jako obiekt typu Products ?

Moje obecne rozwiązanie wygląda następująco, jednak nei działa. I wydaje mi się, że podejście nie jest do końca poprawne:
Sale.java:

public class Sale {

    private LongProperty saleId;
    private SimpleObjectProperty<Product> product;
    private IntegerProperty amount;
    private DoubleProperty price;
    private SimpleObjectProperty<Date>  date;

    public Sale() {
        this.saleId = new SimpleLongProperty();
        this.product = new SimpleObjectProperty();
        this.amount = new SimpleIntegerProperty();
        this.price = new SimpleDoubleProperty();
        this.date = new SimpleObjectProperty<>();
    }

    public long getSaleId() {
        return saleId.get();
    }

    public LongProperty saleIdProperty() {
        return saleId;
    }

    public void setSaleId(long saleId) {
        this.saleId.set(saleId);
    }

    public Product getProduct() {
        return product.get();
    }

    public SimpleObjectProperty<Product> productProperty() {
        return product;
    }

    public void setProduct(Product product) {
        this.product.set(product);
    }
..
.
}

SaleDAO.java:

public class SaleDAO {

    //Use ResultSet from DB as parameter and set Sale Object's attributes and return sale object.
    private static ObservableList<Sale> getSaleList(ResultSet rs) throws SQLException
    {
        ObservableList<Sale> saleList = FXCollections.observableArrayList();
        while (rs.next()) {
            Sale sale = new Sale();
            sale.setSaleId(rs.getLong("sale_id"));
            Product prd = new Product();
           // prd.setProductId(rs.getLong("product_id"));
            prd.setName(rs.getString("name"));
            sale.setProduct(prd);
            sale.setAmount(rs.getInt("amount"));
            sale.setPrice(rs.getDouble("price"));
            sale.setDate(rs.getDate("date"));
            saleList.add(sale);
        }
        return saleList;
    }

    public static ObservableList<Sale> getAll() throws SQLException {      
        try {
            Statement stmt = DatabaseConnector.getConnection().createStatement();
            String sql = "select sale_id, p.name, amount, s.price, \"date\" from sales s, products p where s.product_id = p.product_id";
            ResultSet rows = stmt.executeQuery(sql);
            //Send ResultSet to the getSaleList method and get Sale object
            ObservableList<Sale> saleList = getSaleList(rows);
            stmt.close();
            return saleList;
        }
        catch (SQLException ex){
            ex.printStackTrace();
            System.out.println("SQL select operation has been failed");
            throw ex;
        }
    }
}

Oraz SaleController.java:

public class SaleController {
    @FXML
    private TableView saleTable;
    @FXML
    private TableColumn<Sale, Long>  salesIdColumn;
    @FXML
    private TableColumn<Product, String>  productNameColumn;
    @FXML
    private TableColumn<Sale, Double> priceIdColumn;
    @FXML
    private TableColumn<Sale, Integer> amountColumn;
    @FXML
    private TableColumn<Sale, Date> dateColumn;

@FXML
    private void initialize () {    

        salesIdColumn.setCellValueFactory(cellData -> cellData.getValue().saleIdProperty().asObject());
        productNameColumn.setCellValueFactory(cellData -> cellData.getValue().nameProperty());
        priceIdColumn.setCellValueFactory(cellData -> cellData.getValue().priceProperty().asObject());
        amountColumn.setCellValueFactory(cellData -> cellData.getValue().amountProperty().asObject());
        dateColumn.setCellValueFactory(cellData -> cellData.getValue().dateProperty());

        try {
            //Get all Sales information
            ObservableList<Sale> salesData = SaleDAO.getAll();     
            //Populate Sales on TableView
            saleTable.setItems(salesData);
         //   populateSales(salesData);
        } catch (SQLException e){
            System.out.println("Error occurred while getting sales information from DB.\n" + e);
        }

    }
}

Trochę sie rozpisałem i wrzuciłem dużo kodu, ale chyba tak widać najlepiej zamiar i podejście.
Błąd wyskakuje przy próbie wyświetlenia:
Caused by: java.lang.ClassCastException: model.Sale cannot be cast to model.Product

jeśli wykomentuje poniższą linijkę, program się kompiluje (ale oczywiście nic się nie wyświetla bo nie ma jak :P )

saleTable.setItems(salesData); 

Z góry dziękuję za pomoc

1 odpowiedź

0 głosów
odpowiedź 26 października 2017 przez mbabane Szeryf (79,260 p.)
wybrane 26 października 2017 przez fusemul
 
Najlepsza

Wydaje mi się że problem leży tutaj:

@FXML
private TableColumn<Product, String>  productNameColumn;

Ponieważ cała lista (i cale TableView) i tak jest typu Sale, a tutaj próbujesz wstawić inny typ. 

komentarz 26 października 2017 przez fusemul Użytkownik (710 p.)
to prawda, lista jest typu Sale, ale typ Sale zawiera typ Product, z którego próbuję wyświetlić 'name'. Tak więc jak można byłoby to inaczej rozwiązać? Zmienić model, aby klasa Sale zawierała zmienne id, name(od produktu, zamiast produkt_id), amount, price i date? Ale wtedy klasa nie będize odwzorowaniem tabeli w bazie danych, a tak chyba nie powinno byc
komentarz 26 października 2017 przez mbabane Szeryf (79,260 p.)
edycja 26 października 2017 przez mbabane

Sa dwa sposoby, albo:

TableColumn<Sale, String> columnX;

I wtedy trzeba np. tak:

columnX.setCellValueFactory(cellData -> cellData.getValue().getProduct().nameProperty());

Lub

TableColumn<Sale, Product> columnX;

columnX.setCellValueFactory(cellData -> cellData.getValue().productProperty();

Przy czym wtedy do wyświetlenia wykorzystywana będzie metoda toString() klasy Product. Na ten moment nie wiem czy jest jakiś sposób aby, nie korzystać z metody toString() wykorzystując to rozwiązanie.

1
komentarz 26 października 2017 przez fusemul Użytkownik (710 p.)
dzieki wielkie, pierwszy sposob zadzialal :)

pozdrawiam

Podobne pytania

+1 głos
1 odpowiedź 380 wizyt
pytanie zadane 27 lipca 2022 w Java przez michal441599 Użytkownik (530 p.)
0 głosów
1 odpowiedź 564 wizyt
pytanie zadane 30 sierpnia 2018 w Java przez deti27 Nowicjusz (180 p.)
0 głosów
1 odpowiedź 545 wizyt
pytanie zadane 7 czerwca 2017 w Java przez Mariusz Dobrogosz Nowicjusz (180 p.)

93,434 zapytań

142,429 odpowiedzi

322,661 komentarzy

62,797 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

...