# Lagerprogramm mit Datenbanken



## Thomas.JJu (1. Sep 2016)

Hallo Leute,
ich lese mich schon seit längere Zeit durch das Forum und mir wurde dadurch schon oft weitergeholfen. Nun bin ich aber an einem Punkt angekommen wo ich nicht weiter kommen und auchn och kein Thema darüber gefunden haben. Ich hoffe ihr könnt mir helfen.
Ich erkläre mal mein Problem.  Ich arbeite privat an ein Lagerprogramm( nicht für die Schule, bin auch kein Student). Ich habe die grobe Oberfläche schon fertig. Ich habe mein Programm auch mit der Datenbank verbunden und man kann in mein Programm Daten eingeben und die werden dann in der Datenbank (mysql) gespeichert. Die Daten lassen sich auch abrufen, löschen und bearbeiten. Nun möchte ich aber gerne ein "Bestellfenster" erstellen. Das Fenster hat 2 Textfield in dem man Artikelnummer und Menge eingeben soll und ein Button mit bestellen. Wenn man auf Bestellen drückt sollen die Daten die ich eingeben habe aus der vorhanden datenbank gelesen werden und dann in einer anderen Tabelle angezeigt werden. Wenn ich die Artikelnummer und Menge eingebe und die existieren in der Dantenbank nicht sollte es nicht möglich sein etas zu bestellen.
Ich hoffe ihr wisst wie ich das meine :/

Bis jetzt ist der Code so :

```
JButton btnBestellenTest = new JButton("Bestellen Test");
     btnBestellenTest.addActionListener(new ActionListener() {
       public void actionPerformed(ActionEvent arg0) {
         try{
           String query="insert into HalleAchtListe(Artikelnummer,Menge) values (?,?)";
          
           PreparedStatement pst=connection.prepareStatement(query);
           pst.setString(1,tfBArtikel.getText() );
           pst.setString(2,tfBMenge.getText());
          
           pst.execute();
           JOptionPane.showMessageDialog(null,"Artikel eingelagert!");
          
           pst.close();
          
         }catch( Exception e){
           e.printStackTrace();
         }
       }
     });
```
Ich weiß das , dass so nicht klappt aber ich weiß einfach nicht weiter.

mfg. Jü


----------



## kiwara (1. Sep 2016)

Ich glaube dein Problem liegt weniger am Code/Programm, sondern schon in der DB. Ich weiß nicht wie diese aussieht, wenn sie aber richtig designt ist, sollte die Tabelle aber einen ForeignKey-Check haben, sprich nur wenn es den Artikel gibt, kann man auch den Wert speichern.
Gibt es den Aritkel(bzw. die Nummer) nicht, wirft die DB einen Fehler.

Aber wenn du schon ein PreparedStatement verwendest(völlig richtig), wieso parst du den Text nicht zu einem Int und ruft die Entsprechende setInt Methode auf?


----------



## Thomas.JJu (1. Sep 2016)

Also in der Datenbank gibt es die ID,( die sich selber immer um 1 erhöt), Artikelnummer,Artikelbezeichnung, Menge und Lagerort. Und wenn ich was Bestelle soll nur Artikelnummer und Menge eingegeben werden. Das soll dann automatisch aus der Datenbank gelesen werden. Ich weiß nicht ob das so möglich ist wie ich es mir vorstelle ?


----------



## kiwara (1. Sep 2016)

Das heißt du hast nur eine Tabelle?
Die Frage ist, wenn du etwas bestellst, wobei ich hier mal annehme, dass bestellen bedeuten soll die Menge im Lager des bestellten Artikels wird (über kurz oder lang) verringert, wieso du dann in dieselbe Tabelle etwas hineinschreiben möchtest.
Wenn das so der Fall ist, würde es sich sehr lohnen eine neue Tabelle zu erstellen, wo dann die Bestellungen rein gehen.
Oder versteh ich da irgendwas falsch?


----------



## Joose (1. Sep 2016)

Es wäre praktisch wenn du grob dein Datenbankmodell zeigst und beschreibst.
Und dann natürlich bei was genau du hängst  bei der Überprüfung ob die eigebene ID bzw. Menge vorhanden ist?


----------



## Thomas.JJu (1. Sep 2016)

Ich hab mich falsch ausgedrückt. Also ich habe eine Tabelle in meiner Datenbank in der hab ich (Id, Artikelnummer,Artikelbezeichnung , Menge und Lagerort) In der sind auch schon Artikel drinn. Nun soll beim  Programm beim Bestellen nur Artikelnummer und Menge eingegben werden. Dies soll dann aus der vorhanden Tabelle ausgelesen werden und in einer Jtable eingetragen werden was bestellt wurde. 

Ich hoffe ich konnte das bessser darstellen was ich meine


----------



## Joose (1. Sep 2016)

Du musst zuerst mal ein Statement ausführen was überprüft ob die eingegeben Artikelnummer vorhanden (in ausreichender Menge) vorhanden ist.
Sollte dies erfolgreich sein kannst du den Eintrag im JTable machen.

So in der Art 
`SELECT * FROM Tabellenname WHERE Artikelnummer = ? AND SUB(Menge - ?) > 0;` 
Als Ergebnis bekommst du dann den entsprechenden Datensatz.


----------



## Thallius (1. Sep 2016)

Willst du jetzt Artikel zum Lager hinzufügen oder entfernen? Wahrscheinlich verstehen wir das hier alle falsch und du meinst mit Bestellen nicht, dass ein Kunde was aus dem Lager bestellt und es deshalb weniger wird, sondern Du willst es fürs Lager bestellen und entsprechend die Anzahl im Lager erhöhen?


----------



## Joose (1. Sep 2016)

Der User darf Artikelnummern + Menge angeben (mehrmals), das Programm prüft ob gewünschter Artikel existiert (bzw. die Menge vorhanden ist).
Wenn ja dann werden die Daten in ein JTable geschrieben (wahrscheinlich ala temp. Bestellformular welches am Ende abgeschickt werden kann.


----------



## Thomas.JJu (1. Sep 2016)

Ich hab hier mal ein paar Bilder damit ihr sehen könnt wie das aussieht. 




Also wenn einer aus dem Lager was bestellt (weil er Ware aus einer andere Halle brauch) soll das aus der vorhanden Tabelle ausgelesen werden und dann auf der Seite Bestellung angezeigt werden. Was bestellt wurde. Es soll aber nur möglich sein etwas zu bestellen wenn es das auch in der Tabelle gibt.


----------



## Thallius (1. Sep 2016)

Finde ich zu kompliziert gelöst. Warum machst ud nicht eine JTable mit allen Artikeln und einer Filter Funktion zum Suchen. Dann wird bei einem Klick auf diesen Artikel nur ein Fenster geöffnet in der Du die Menge eingeben kannst. Da die Menge dann schon in der JTable steht (Je nach Mengen kann man es dann ja sogar mit einer ComboBox machen wo man einfach nur die Anzahl auswählt), kannst du in diesem Eingabefenster auch gleich die Menge auf die vorhandene begrenzen. Das ist technisch viel einfacher und für den User auch viel schöner als wenn der da irgendwelche Aritkelnummern abtippen muss..


----------



## Thomas.JJu (9. Sep 2016)

Hallo Leute,
ich hab mein Programm etwas umgeworfen, da eure Ideen die ihr mir gegeben habt einfach viel besser sind als meine.
Nun bin ich aber bei einem neuen Problem angekommen und ich denke das die Lösung total einfach ist, nur komme ich da gerade nicht drauf, vielleicht wisst ihr die Lösung ? =)

Ich zeig euch hier mal ein Bild, damit ihr das  bessser verstehen könnt was ich meine


hier der Code :

```
tableHalleSieben = new JTable();
     tableHalleSieben.addMouseListener(new MouseAdapter() {
       @Override
       public void mouseClicked(MouseEvent arg0) {
         try{
         int row = tableHalleSieben.getSelectedRow();
         String ID_=(tableHalleSieben.getModel().getValueAt(row, 0)).toString();
         String query="select *from HalleAchtListe where ID='"+ID_+"' ";
         PreparedStatement pst=connection.prepareStatement(query);
       
         ResultSet rs=pst.executeQuery();
       
         while(rs.next())
         {       
           tfArtikelNr.setText(rs.getString("Artikelnummer"));
           tfArtikelBez.setText(rs.getString("Artikelbezeichnung"));
           tfMenge.setText(rs.getString("Menge"));
           tfLagerort.setText(rs.getString("Lagerort"));
           taBemerkungzwei.setText(rs.getString("Bemerkung"));
         
         }
         pst.close();
       }catch(Exception ex){
         ex.printStackTrace();
        }
       
       }
```

Ich hoffe ihr wisst was ich falsch mache


----------



## mrBrown (9. Sep 2016)

Gibt `rs.getString("Bemerkung")` denn das richtige zurück?

Als generelle Anmerkung, du solltest Logik und View trennen. Das ganze Laden der Daten sollte aus der View raus, und die Daten des ResultSets kann man besser in einem extra Objekt kapseln


----------



## Thallius (9. Sep 2016)

Aus diesem Grund benutzt man übrigens NIEMALS SELECT *


----------



## Thomas.JJu (9. Sep 2016)

Ich wüsste jetzt ehrlich gesagt nicht wie ich das umschreiben soll , wie ihr das meint? Bin noch ziemlich am Anfang meiner Kentnisse


----------



## Thallius (9. Sep 2016)

Du solltest Deinen Code einfach besser strukturieren. Das ist gerade am Anfang sehr viel Lern- und Leseaufwand, hilft Dir aber viel saubereren und besser wartbaren und auch wesentlich fehler unanfälligen Code zu produzieren.

Gerade am Anfang neigt man dazu wie du, alles in einen Sourcecode zu schreiben. Das ist generell falsch. Man sollte versuchen so viele einzelne kleine Sourcen zu schreiben wie es geht. Dadurch erhöhst du die Übersicht und vor allem die Wiederverwendbarkeit. Das Laden der Daten mit dem Query zum Beispiel wirst du sicher an ganz vielen Stellen im Code brauchen. Änderst du nun dein Datenmodell und fügst eine weitere Spalte zu deiner Datenbank hinzu, dann musst du an etlichen Stellen Deinen Code bearbeiten. Wenn Du das Ganze in ein Model kapselst welches sich nur darum kümmert die Daten zu pflegen dann wird das alles viel einfacher.

Am besten fängst du mal damit an dir das MCV Protokoll anzueignen und versuchst das umzusetzen.

http://openbook.rheinwerk-verlag.de/oo/oo_06_moduleundarchitektur_001.htm

Gruß

Claus


----------



## mrBrown (9. Sep 2016)

Thallius hat gesagt.:


> Aus diesem Grund benutzt man übrigens NIEMALS SELECT *


Das man es nicht machen sollte ist klar, aber was ist denn hier "dieser Grund"?


----------



## Thomas.JJu (12. Sep 2016)

Vielleicht versteh das ich falsch aber ich hab den Sourcecode noch unterteilt, in sieben klassen


----------



## mrBrown (12. Sep 2016)

7 Klassen sind nicht sonderlich viel.
Ich seh allein in dem Codestück oben min 3 Klassen (bzw 2 mehr, als jetzt da sind)


----------



## JStein52 (12. Sep 2016)

Wir können hier noch Grundsatzdiskussionen führen oder du guckst einfach mal was bei:

rs.getString("Bemerkung")

zurückkommt indem du es ausgibst !


----------



## artchi (16. Sep 2016)

Der Thomas hat ein konkretes Problem. Ich denke nicht, das er weiter kommt, wenn man ihm sagt, er soll sich erstmal das aneignen, was andere im 8-Stunden-Job erst in Jahren lernen (Software-Architektur). Da müsste er erstmal Bücher über OOA, OOD und OOP lesen, verstehen und anwenden, und wäre immer noch nicht so weit wie ein Profi. Dabei will er nur als Hobby (so habe ich es verstandne) eine Anwendung schreiben.


----------



## mrBrown (16. Sep 2016)

artchi hat gesagt.:


> Der Thomas hat ein konkretes Problem. Ich denke nicht, das er weiter kommt, wenn man ihm sagt, er soll sich erstmal das aneignen, was andere im 8-Stunden-Job erst in Jahren lernen (Software-Architektur). Da müsste er erstmal Bücher über OOA, OOD und OOP lesen, verstehen und anwenden, und wäre immer noch nicht so weit wie ein Profi. Dabei will er nur als Hobby (so habe ich es verstandne) eine Anwendung schreiben.



Und der Lösungsansatz steht in #13 als Antwort auf seine Frage in Beitrag #12 

Kapselung sollte man auch wenn man es nur als Hobby macht so früh wie möglich lernen, das erspart einem viele Probleme. Das ist ja nun wirklich kein Hexenwerk und erfordert mit Sicherheit nicht viele Jahre in einem 8h-Job...


----------

