• 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)

Object Storage Arubacloud
0 głosów
454 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,280 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,280 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ź 181 wizyt
pytanie zadane 27 lipca 2022 w Java przez michal441599 Użytkownik (530 p.)
0 głosów
1 odpowiedź 455 wizyt
pytanie zadane 30 sierpnia 2018 w Java przez deti27 Nowicjusz (180 p.)
0 głosów
1 odpowiedź 490 wizyt
pytanie zadane 7 czerwca 2017 w Java przez Mariusz Dobrogosz Nowicjusz (180 p.)

92,576 zapytań

141,426 odpowiedzi

319,652 komentarzy

61,961 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.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...