Zugriff auf die DatenBank

Status
Nicht offen für weitere Antworten.

PollerJava

Top Contributor
Hallo nochmal,

in meinem Programm lese ich alle 500ms (damit ich mein Programm stresse) aus einer DatenBank aus,
Der Benutzer kann parallel eine Aktion starten, in der etwas in die DatenBank geschrieben wird,

Code:
private Connection con;    // für das Lesen alle 500ms (nicht static) wird geöffnet und wieder geschlossen

protected static Connection con1;   // für Benutzerinteraktionen, bleibt bestehen

wenn der Benutzer jetzt etwas in die DatenBank schreiben will, dann kommt es darauf an, wann das ist.
Passiert dies zwischen den 500ms dann funktionierts, ansonsten bekomme ich die Fehlermeldung Reset is closed,

Meine Frage wäre jetzt, wie man das machen kann, das alle 500ms etwas aus der DB gelesen wird und dass ich auch in die DB etwas schreiben kann, wie macht man das normal (lesen stoppen und schreiben und dann wieder lesen???)


lg
 
T

tuxedo

Gast
Um alle 500ms zu lesen musst du doch nciht jedesmal die Verbindung komplett kappen, oder? Versteh den Hintergrund nicht.

Das was du suchst ist so eine Art Pool der die Lese-/Schreibaktionen verwaltet ...


- Alex
 
W

Wuschel87

Gast
mach es über threads(wirst ja warscheinlich ehs chon tun), und wenn der knopf zum schreibeng edrückt wird stoppst den thread mit dem lesebefehl, dann den schreibbefehl ausführen und thread wieder starten ;) sollte klappen

(vorher vielleicht noch die connection schließen und wiede röffnen )

lg Wuschel
 
T

tuxedo

Gast
Ständig die Connection neu aufzubauen ist doch nicht performant?!

Wenn's drum geht zu verhindern dass gleichzeitig gelesen oder geschrieben wird ist ein Pool/Queue doch besser:

Eine Klasse die Lese und Schreibvorgänge entgegen nimmt und diese in einen Puffer schreibt. Ein Thread in dieser Klasse arbeitet dann dan Puffer Stück für stück ab. Ist halt nur dumm wenn man da jeweils noch das Ergebnis der Abfrage haben will... Dann ist der Puffer eher blöd. Dennoch wäre die Klasse mit den 2 Methoden für lesen und schreiben nicht verkehrt. Man sollte dann halt nur diese 2 Methoden synchronized machen damit sie nicht gleichzeitig aufgerufen werden können.

- Alex
 

PollerJava

Top Contributor
Naja, irgendwer hat mal in diesem Forum geschrieben, nach dem Öffnen der Verbindung:

Code:
 public Connection getConnection()
        {
        try {
            con = DriverManager.getConnection("jdbc:firebirdsql:localhost:c:\\...", username, passwort);
            }
        catch (Exception e)
            {   
            System.out.println();
            }
        return con;
        }

sollte die Verbindung wieder geschlossen werden:



Code:
public void closeConnection()
        {
        try {
            con.close();
            }
        catch (Exception e)
            {
            System.out.println();
            }
        }

Kann man das pauschal irgendwie sagen, wie lange das schließen und das öffnen der Verbindung benötigt??

Wie würde das mit dem Pool funktionieren, gibts da ein Beispiel dafür?

lg
 
T

tuxedo

Gast
Was du schließen sollst ist das ResultSet, sobald du die für dich wichtigen Daten extrahiert hast um damit weiter zu arbeiten.

Aber jetzt stell dir ein Programm vor das viele Anfragen an die DB macht... Und für jede Anfrage baust du die verbindung auf, führst sie aus und beendest die Verbindung wieder...

Ich hab deinen ersten Post jetzt nochmal durchgelesen und ihn diesmal vermutlich verstanden:

Wenn du die Verbindung aufrecht erhälst, hast du das Problem nicht mehr mit dem "wann erfolgt der Zugriff". Du scheinst schlicht und einfach "ResultSet schließen" mit "Connection schließen" verwechselt zu haben.

Vergiss für's erste das mit dem Pool wieder...

btw:
statt
Code:
catch (Exception e){
System.out.println();
}

wirst du hoffentlich besser sowas

Code:
catch (Exception e){
e.printStackTrace();
}

machen.. Oder noch besser die Exception ordentlich abfangen und darauf reagieren.

- Alex
 

PollerJava

Top Contributor
Und wie soll ich das mit meinen 2 Verbindungen machen (con und con1), Das stört mich ziemlich,
Ist es OK, eine Verbindung (con) zu haben und über diese alles durchzuführen und soll diese static sein oder eine Objektvariable?

lg und vielen Dank
 
T

tuxedo

Gast
Ähm, du stehst gerade etwas neben dir:

Im Normalfall hast du deine einzige Connection zur DB die am besten irgendwo am Programmbeginn geöffnet wird, und vor dem Programmbeenden geschlossen wird. Dazwischen gehen alle Anfragen an die DB über diese eine Connection. Diese Static zu machen finde ich keine gute Idee. Du solltest dein Programm eher in verschiedene Schichten aufbauen:

GUI-Schicht
Logik-Schicht
DB-Schicht

Wenn jetzt irgendwo in der GUI über einen Button eine Abfrage ausgelöst wird geht das Event runter in die Logikschicht. Da wird geschaut: Was will der User damit eigtl? Und die Logikschicht macht dann über die DB-Schicht die Abfrage. Die Schichten solltest du miteinander via Objektreferenzen etc. verlinken. D.h. die GUI-Schicht hat eine Referenz zur Logikschicht. Due GUI kann hier in ihren "actionPerformed"-Methoden, Methoden in der Logik aufrufen. Die Logikschicht hat eine Referenz zur DB-Schicht. Die von der GUI aufgerufenen Logik-Methoden rufen dann wieder DB-Methoden in der DB-Schicht auf.

Wenn du das noch schön über Interfaces regelst kannst du die Schichten beliebig austauschen ;-) Beispielsweise ne Andere GUI drauf setzen oder die DB-Schicht durch eine Datei-basierte-DB-Schicht ersetzen...

- Alex
 

PollerJava

Top Contributor
AJ das MVC (D) - Muster hab ich implementiert nur der Datenbankzugriff hat nicht ordentlich funktioniert da ich, wie ich nur eine con gehabt habe, immer ein ResultSet is closed bekommen habe,
Mit 2 hats dann funktioniert -> und das irgendwie möchte ich eben jetzt auflösen,

vielen dank für die Hilfe,

lg
 

PollerJava

Top Contributor
alex0801 hat gesagt.:
Du scheinst schlicht und einfach "ResultSet schließen" mit "Connection schließen" verwechselt zu haben.

http://www.java-forum.org/de/viewtopic.php?p=323907 // vorletzter Beitrag,


Hier hab ich das mit dem Schließen der Verbindung her (Zitat von Gast: "Eigentlich gehört die Verbindung auch geschlossen")

Werds aber jetzt umschreiben, sodass ich nur das ResultSet schließe,

lg und danke für die Tipps
 
T

tuxedo

Gast
Also
ich muss dem Gast in verlinkten Beitrag ein wenig widersprechen:

Wenn ich Prepared Statements verwende, und immer mal wieder die gleiche Art von Anfrage mache, dann ist es blödsinn die Verbindung zu beenden. Grund: Prepared Statements haben eine Lebensdauer, begrenzt auf die aktuelle Verbindung. Schließe ich die Verbindung hab ich den Vorteil der P.S., dass das Statement in der DB schon "vorgefertigt" ist und demnach etwas schneller ausgeführt werden kann, nicht mehr.

Wenn du natürlich genau weißt, dass du die nächste Zeit definitiv keine DB-Anfrage in deinem Programm machst (also beispielsweise ausschließlich bei Programmstarte), dann machts auch keinen Sinn die Verbindung offen zu halten.

Ach ja, noch was: Je nach DB-Config wird der Db-Server die Verbindung nach einer gewissen Zeit Inaktivität kappen. D.h. du solltest darauf vorbereitet sein und sowas ggf. per Exception abfangen und die Verbindung neu aufbauen.

- Alex
 

PollerJava

Top Contributor
Hallo nochmal,

ich hab jetzt folgendes gemacht (alles ohne try-catch):

Code:
public Connection  createDBConnection(String pfad, String username, String passwort)
        {   
        return con = DriverManager.getConnection(pfad, username, passwort);    
        }

public Connection getDBConnection()
        {       
        return con;
        }

 public void closeDBResultSet()
        {      
        rs.close();         
        }


Code:
Klasse DBDriver:

// diese Methode liest aus der DatenBank aus, wenn der Benutzer einen Button drückt
public synchronized void findFile(String zeitstempel, Timestamp tsAktStart, Timestamp tsAktEnd, String dBName)              
        {                           
        stmt = getDBConnection().prepareStatement(String.format("SELECT zeitstempel, wert FROM %s WHERE zeitstempel BETWEEN ? AND ?", dBName));
        stmt.setTimestamp(1, tsAktStart);
        stmt.setTimestamp(2, tsAktEnd);
        rs = stmt.executeQuery();  
        while(rs.next())                        
             dBWerte.put(rs.getString("zeitstempel"), rs.getFloat("wert"));                          
        stmt.close();
        closeDBResultSet();
        aktuell = null;
        calendar = null;
        tsAktStart = null;
        tsAktEnd = null;
        }


// diese Methode schreibt z.B.: alle 2 Sekunden in die Datenbank
protected synchronized void fillTable(String tableName, Timestamp kommen, float wert, Timestamp gehen, Timestamp quit, String alarmNr, int var1, int var2)
       {
       PreparedStatement stmt = null;          
       stmt = getDBConnection().prepareStatement(String.format("INSERT INTO %s (zeitstempel, wert) VALUES ( ? , ?)", tableName));
       stmt.setTimestamp(1, kommen);
       stmt.setFloat(2, wert);
       stmt.executeUpdate();
       stmt.close();
       closeDBResultSet();  
       }

Ab und zu bekomme ich dann folgende Fehlermeldung und ich weiß nicht, wie ich das lösen kann.
Ich vermute mal, dass beide oberen Methode auf die DB zugreifen und die erste, die fertig ist, den ResultSet schließe und ich dann eben die fehlermeldung von unten bekomme:

Code:
Fehler in der Klasse DBDriver beim Auslesen aus der DB: org.firebirdsql.jdbc.FBSQLException: Result set is already closed.
org.firebirdsql.jdbc.FBSQLException: Result set is already closed.
        at org.firebirdsql.jdbc.FBStatementFetcher.checkClosed(FBStatementFetcher.java:232)
        at org.firebirdsql.jdbc.FBStatementFetcher.fetch(FBStatementFetcher.java:187)
        at org.firebirdsql.jdbc.FBStatementFetcher.next(FBStatementFetcher.java:137)
        at org.firebirdsql.jdbc.FBResultSet.next(FBResultSet.java:250)
        at datenbank.DBDriver.findFile(DBDriver.java:230)
        at component.CheckList.setShift(CheckList.java:113)
        at component.Trend.aktTrend(Trend.java:537)
        at component.TrendAkt.run(TrendAkt.java:26)
        at java.util.TimerThread.mainLoop(Timer.java:512)
        at java.util.TimerThread.run(Timer.java:462)
 
M

maki

Gast
Ab und zu bekomme ich dann folgende Fehlermeldung und ich weiß nicht, wie ich das lösen kann.
Ich vermute mal, dass beide oberen Methode auf die DB zugreifen und die erste, die fertig ist, den ResultSet schließe und ich dann eben die fehlermeldung von unten bekomme:
Hast du mehrere Threads am laufen?
 
T

tuxedo

Gast
;-)

Wenn du ein Statement hast, das irgendwas in der Tabelle selektiert, dann solltest du das Resultset erst dann schließen, wenn du die abgefragten Daten aus dem RS rausgeholt hast.

Das ist das eine. Das andere ist:

Deine fillTable-Methode erzeugt gar kein offensichtliches Resultset, und dennoch schließt' du's. Schau dir doch mal den "return"-Wert von executeUpdate(); an ...

- Alex
 
M

maki

Gast
Hast du mehrere Threads am laufen?
Meine Frage kann ich seber beantworten: Ja, du hast mehrere Threads am laufen.

Spätestens jetzt wäre es an der Zeit, eine vernünftige DB Zugriffsschicht zu implementieren, mit DAOs.
Oder du nimmst einfach iBatis.
 

PollerJava

Top Contributor
JA, die Methode

Code:
protected synchronized void fillTable(String tableName, Timestamp kommen, float wert, Timestamp gehen, Timestamp quit, String alarmNr, int var1, int var2)
       {
       PreparedStatement stmt = null;         
       stmt = getDBConnection().prepareStatement(String.format("INSERT INTO %s (zeitstempel, wert) VALUES ( ? , ?)", tableName));
       stmt.setTimestamp(1, kommen);
       stmt.setFloat(2, wert);
       stmt.executeUpdate();
       stmt.close();
       closeDBResultSet(); 
       }

rufen 5 Threads auf:

Code:
for (int i = 0; i < 5; i++)
dBTimer.scheduleAtFixedRate(new DBWriter(..., ... usw));             
            
        
    
public void run()                                                           // Werte in die Datenbank schreiben
        {
        fillTable(tableName, kommen, wert, gehen, quit, alarmNr, var1, var2);
        }
 

PollerJava

Top Contributor
alex0801 hat gesagt.:
;-)

Deine fillTable-Methode erzeugt gar kein offensichtliches Resultset, und dennoch schließt' du's. Schau dir doch mal den "return"-Wert von executeUpdate(); an ...

- Alex


Ja stimmt, danke (Rückgabe ist ein int)
 

PollerJava

Top Contributor
naja, das ist das erste mal, dass ich von mehreren Seiten auf eine Datenbank zugreife und von DAOs hab noch nie etwas gehört obwohl ich das Java Handbuch und Java ist auch eine Insel und das Java Kompnedium gelesen habe (Vielleicht hab ichs auch überlesen, hab aber versucht, sehr genau zu lesen),

Gibts da irgendeinen Code, denn ich auch verstehe und den ich leicht implementieren kann,

http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html scheint ja ziemlich kompliziert zu sein,

Ich verwende die fireBird- Datenbank,

lg und vielen Dank
 
M

maki

Gast
naja, das ist das erste mal, dass ich von mehreren Seiten auf eine Datenbank zugreife und von DAOs hab noch nie etwas gehört obwohl ich das Java Handbuch und Java ist auch eine Insel und das Java Kompnedium gelesen habe (Vielleicht hab ichs auch überlesen, hab aber versucht, sehr genau zu lesen),
DAOs istso was wie ein "best practice", gabs vor Java auch schon.

Gibts da irgendeinen Code, denn ich auch verstehe und den ich leicht implementieren kann,

http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html scheint ja ziemlich kompliziert zu sein,
iBatis hat das schon implementiert, dafür musst du iBatis lernen ;)
Du brauchst übrigens die SQL Maps nicht zu verwenden, kannst das DAO Framework auch unabhängig verwenden.

Kompliziert ist es nicht, eine AbstractFactory eben.

Oder diese Möglichkeiten:

1. Du sorgst dafür, das der zugriff auf die Connection, das Resulset und das Statement synchronisiert sind.

2. Gib jedem Thread seine eigene Connection
 

PollerJava

Top Contributor
maki hat gesagt.:
Kompliziert ist es nicht, eine AbstractFactory eben.

Oder diese Möglichkeiten:

1. Du sorgst dafür, das der zugriff auf die Connection, das Resulset und das Statement synchronisiert sind.

2. Gib jedem Thread seine eigene Connection


Also mit FactoryMethode und AbstarctFactory kenn ich mich halbwegs.

Jedem Thread seine eigene Connection geben, möchte ich eher vermeiden da ich nicht nur 5 Threads haben kann sondern unbekannt viele oder auch wenige,
Mir wird also nichts anderes übrig bleiben als mich in DAO zu stürzen, oder,
Hoffentlich habe ich nicht zu lange den PandaBär- Effekt,

Ich hätte noch ein paar Fragen:


Ich hab mir jetzt das Tutorial von iBatis durchgelesen kann dieses aber leider nicht verwenden, da keine XML- Datei (ausser für die des Kunden) angelegt werden sollen (Pflichtenheft),

Hab ich das richtig verstanden, dass ein DAO also ein Entwurfsmuster ist?

Kann ich das DAO auch in einer Java- Applikation verwenden (DAO ist ja für Enterprise) bzw. wie viel Adaptionsaufwand ist das und gibt es Code für eine DAO in einer Java- Applikation,

Vielen Dank für Eure Tipps!!!

lg
 
T

tuxedo

Gast
Kann mir im übrigen nicht vorstellen dass im Pflichtenheft steht "Es dürfen keine XML-Dateien benutzt werden" .. Nur für den Fall dass du das Turorial nur Oberflächlich angeschaut hast: In den XMLs steht nur, wie Teile der Datenbank auf ein Java-Objekt gemappt werden. Die XMLs selbst stellen keine Datenbank dar sondern nur eine Art Konfigurations-Datei.

Zu DAO: http://de.wikipedia.org/wiki/Data_Access_Object

Ich hab bis jetzt nicht allzuviele APIs in Bezug auf DAO in der Hand gehabt, aber alle die ich in der hand hatte haben eine Mapping-Beschreibung in Dateiform benutzt, und das Format in der Datei war nunmal XML.

Prinzipiell kannst du dir's ja selbst basteln wenn du _unter gar keinen Umständen_ XML Dateien für die Konfiguration benutzen darfst. Aber warum das Rad neu erfinden wenn wenn es schon Libs gibt die das machen (und halt leider gottes XML für's mapping verwenden).

- Alex
 

PollerJava

Top Contributor
naja im Pflichtenheft steht, es ist im Projektordner eine Datei anzulegen in dem die Konfigurationsdatei und die Passwort- Datei zu hinterlegen ist und das ist ziemlich streng gemeint aber ich werd mich da jetzt darüber hinwegsetzt und es so machen,

Ich hab jetzt nach Java- Code gesucht, bin aber noch auf nichts gestoßen,
Wieviel Aufwand ist das, von meinem Stand weg das DAO zu implementieren und kann ich meine momentane Implementierung im Großen und Ganzen so lassen oder muss ich viel ändern?

lg
 
M

maki

Gast
Also mit FactoryMethode und AbstarctFactory kenn ich mich halbwegs.
Das ist schon mal gut, eine DAOFactory ist nämlich nix anderes, wenn du nur eine DB hat könntest du auch gleich eine ConcreteFactory benutzen, ohne den Umweg über die AbstractFactory.

Jedem Thread seine eigene Connection geben, möchte ich eher vermeiden da ich nicht nur 5 Threads haben kann sondern unbekannt viele oder auch wenige,
Mir wird also nichts anderes übrig bleiben als mich in DAO zu stürzen, oder,
Du musst keine DAOs einsetzen wenn sie dich verwirren.
Allerdings sehe ich keinen Grund, warum nicht jeder Thread seine eigene Connection haben sollte, lässt sich sehr elegant lösen mithilfe eines ConnectionPools (hatte ich hier schon gepostet).

ch hab mir jetzt das Tutorial von iBatis durchgelesen kann dieses aber leider nicht verwenden, da keine XML- Datei (ausser für die des Kunden) angelegt werden sollen (Pflichtenheft),
Da hast du ein paar Dinge verwechselt:
1. Die XML Dateien gehören zu deinem Sourcecode, darin werden keine fachlichen Daten gespeichert, es handelt sich um Konfigurationsdaten und Quellcode (dein SQL steckt da drinnen).
2. Du brauchst keine SQL Maps, du brauchst das DAO Framework: http://ibatis.apache.org/docs/java/pdf/iBATIS-DAO-2_en.pdf
Ignorier einfach die SQLMaps, an ihrer Stelle führst du dann JDBC Aufrufe direkt aus, wenn dich die SQLMaps verwirren (sind aber wirklich besser ;) )

Hab ich das richtig verstanden, dass ein DAO also ein Entwurfsmuster ist?
Ja :)

Kann ich das DAO auch in einer Java- Applikation verwenden (DAO ist ja für Enterprise) bzw. wie viel Adaptionsaufwand ist das und gibt es Code für eine DAO in einer Java- Applikation,
DAO ist nicht nur für Enterprise und schon gar nicht nur für Java, es macht keinen Unterschied ob es eine Desktop Anwendung ist oder in einem JEE Umgebung läuft (in der JEE gibt's mehr Mölichkeiten der Konfiguration, das ist alles).

IMHO sollte jeder, der einen DB Zugriff implementiert sich zumindest mal mit DAOs auseinandersetzen.



Willst du eine schnelle Lösung, dann muss jede Methode, die einen DB Zugriff macht:
- nur lokale Variablen verwenden, keine Instanz-und schon gar keine Klassenvariablen!

- jedesmal eine neue(*) Connection holen, ein neues Statement erzeugen und dann natürlich ein neues Resultset benutzen

- alle Resourcen (Connection, Statement ResultSet) müssen nach ihrer Benutzung wieder geschlossen werden.

* Wenn du einen ConnectionPool verwendest, ist das keine Geschwindigkeitsverlust.
 
T

tuxedo

Gast
PollerJava hat gesagt.:
naja im Pflichtenheft steht, es ist im Projektordner eine Datei anzulegen in dem die Konfigurationsdatei und die Passwort- Datei zu hinterlegen ist und das ist ziemlich streng gemeint aber ich werd mich da jetzt darüber hinwegsetzt und es so machen,

MIr scheint du hast nicht ganz verstanden was ein Pflichtenheft ausmacht. Im Pflichtenheft steht hauptsächlich drin was gemacht werden MUSS (deswegen auch "Pflicht"). D.h. du kannst nicht einfacg die Konfigurationsdatei weglassen. Solange aber keine Kundenanfoderung besagt "Das Projekt DARF NUR aus .CLASS-Files und der Konfigurationsdatei" bestehen, darfst nach Lust und Laune weitere Dateien hinzunehmen. Und wie maki ja schon geschrieben hat, gehören die XML-Files von iBatis mit zum Quelltext und sind i.d.R. nicht für den Benutzer gedacht.

- Alex
 

PollerJava

Top Contributor
Vielen Dank für die Erklärungen!!!
Ich sehe momentan den Baum vor lauter ....

Ich werd mich mal in die DAOs einlesen, ich will sie auch verwenden und bin auch sehr interessiert in Entwurfsmuster (Hab das Buch von O'Reilly -> Entwurfsmuster gelesen und setze immer mehr ein wos Sinn macht, von DAO stand aber da nichts drinnen, is wahrscheinlich zu speziell o.ä)
aber der liebe Zeitdruck ist mom. ziemlich hoch aber was solls,

Dankeschön,

lg
 
M

maki

Gast
Der grösste Vorteil von DAOs ist, dass es die DB technologie kapselt , d.h. wenn du später andere DB arten verwendest (Hibernate, XML, etc. pp.) musst du deine fachlichen/GUI Klassen nicht mitanpassen, die Änderungen bleiben Transparent.
Dein JDBC und SQL Code ist nicht über die ganze Anwendung verteilt, sondern nur in der DAO Schicht :)

Die SQL Maps sind auch super:
JDBC Code bläht die Sourcen wirklich auf(geschachtete try/catch Blöcke, statements zusammen bauen, werte konvertieren etc., resourcen freigeben ), da gibt es viele Möglichkeiten Fehler zu machen.
Aber zuerst kommen die DAOs ;)
 

PollerJava

Top Contributor
Ja aber wie fange ich an, ich habe mir iBatis-DAO-2_en.pdf durchgelesen und mir das BeispielProgramm JPetstore 5 demo application heruntergeladen,
kann ich mit dem was anfangen bzw. kann ich das verwenden?

lg
 
M

maki

Gast
PollerJava,

das bringt alles nix wenn du nicht verstehst was du da machst.

Eine "out of the box" Lösung gibt es nur, wenn du dich reinliest.
Wenn du das gemacht hast, wirst du keine Grund mehr sehen, iBatis einzusetzen.

Wie gesagt, es geht auch ohne DAOs, um mich selbst zu zitieren:
Willst du eine schnelle Lösung, dann muss jede Methode, die einen DB Zugriff macht:
- nur lokale Variablen verwenden, keine Instanz-und schon gar keine Klassenvariablen!

- jedesmal eine neue(*) Connection holen, ein neues Statement erzeugen und dann natürlich ein neues Resultset benutzen

- alle Resourcen (Connection, Statement ResultSet) müssen nach ihrer Benutzung wieder geschlossen werden.

* Wenn du einen ConnectionPool verwendest, ist das keine Geschwindigkeitsverlust.
Das wäre für dich am einfachsten zu bewerkstelligen.

Wenn du es einfach haben wilst, dann ist das dein Weg.

Willst du es mit Mustern (DAO) lösen, ist iBatis dein Freund, oder du machst es komplett selber.
 

PollerJava

Top Contributor
Nö, ich werds mit den DAOs machen,
also einlesen, verstehen und dann meinen DAO- Code stricken wenn ich das richtig verstanden habe ???:L
 
T

tuxedo

Gast
Ich fand den Weg mit den XMLs sehr einfach und gut erklärt. Zudem hat man den Vorteil nicht den Compiler anwerfen zu müssen wenn sich was an der DB-Struktur ändert, weil man's einfach in der XML ändern kann.

In das Thema "reingefunden" hab ich allein durch das Tutorial.

- Alex
 

PollerJava

Top Contributor
Spalte | Spalte | ...

ich habe mehrere Tabellen, die so aussehen -> String name | Float Wert
und eine Tabelle, die so aussieht -> Timestamp ts1 | Timestamp ts2 | Timestamp ts3 | String str1 | INT i1 | INT i2

für diese Tabellen lege ich mir mal eine XML- Datei an, welche diese Tabellen repräsentieren (wie im Tutorial beschrieben ),

Mein Problem ist, dass die Tabellen in der DB erst erstellt werden, wenn die Applikation das erste mal gestartet wird (ich weiß also nicht, wievielen Tabellen es sind -> wie viel ich in der XML- Datei anlegen muss)

ich verwende dann eben in meiner Klasse an den verschiedenen stellen (in meinen 2 Methoden, wo ich etwas in die DB schreiben will):

Code:
private static final SqlMaapClient sqlMap;
...

sqlMap.insert("insertWieInDerXMLSteht", Datensatz);

Ich frag mich jetzt, ob das mein Problem löst ("ResultSet ist closed"), da ich ja wieder von meinen 5 Threads auf die DB zugreife über die XML- Datei halt, oder?

Wäre sehr dankbar für Hilfe,

lg
 
T

tuxedo

Gast
Ich behaupte jetzt mal dass dein DB-Design schlecht ist wenn die Anzahl der Tabellen variabel ist und sich "ändern" kann. Am besten du erklärst mal genauer das wieso und warum.

Die Sache mit dem ResultSet:

Da wirst du keine Probleme haben da du mit einem Resultset nicht mehr direkt in Berührung kommst. Macht iBatis für dich.
 

PollerJava

Top Contributor
Beim ersten mal starten der Applikation wird aus einer XML- Datei ausgelesen, wieviel Tabellen angelegt werden sollen,

Bestehen die Tabellen schon in der DB und die Appl wird gestartet, dann wird eben in der DB nachgesehen, ob die Tabellen schon bestehen oder nicht und dann eben angelegt oder auch nicht,

Das ist aber eh das geringste Problem,
Da wirst du keine Probleme haben da du mit einem Resultset nicht mehr direkt in Berührung kommst. Macht iBatis für dich.

Also das hab ich dann nocht nicht durchschaut, wo macht den das IBatis? in der Config- XML- Datei?

vielen Dank für die Unterstützung, war ja schon vor der Verzweiflung!!
 
M

maki

Gast
Ähm, wenn du Tabellen abfragen willst, musst du die Tabellen schon kennen bevor dein Programm läuft, sonst wird das nix.

Ich nehme an, die möglichen Tabellen der XML Datei sind dir schon beim kompilieren bekannt?

Also das hab ich dann nocht nicht durchschaut, wo macht den das IBatis? in der Config- XML- Datei?
Das läuft im SqlMap Framework ab, da brauchst du keine Details zu kennen, dafür hast du ja iBatis.
Einen Überblick solltest du dir aber auf jedenfall besorgen, des Verständnisses wegen.

Wichtig für dich ist nur der Rückgabewert deiner DAOs:
- Ein einzelnes Objekt (eines "deiner" Objekte, oder nur HashMaps :) )
- Eine Liste von Objekten (Eine Liste diner Objekte, oder eine Liste von HashMaps)
- Einen numerischen wert für die ID des zuletzt eingefügten Datensatzes (int, long, Integer, Long, etc. pp. ) bei identity feldern.

DAOs eignen sich übrigens hervoragend als Generische Typen, aber das ist was für Fortgeschrittene.
 
T

tuxedo

Gast
Hast du den Sinn und Zweck von iBatis überhaupt verstanden?

Sinn und zweck ist es JDBC und alles was mit SQL zu tun hat aus dem direkten Java-Code zu entfernen. D.h. wenn du das so machst wie in dem Tutorial brauchst du dich um nix mehr kümmern was DB-Verbindungen, Resultsets, Statements etc. angeht (naja, fast, die XML musst du halt erst anlegen).

Intern macht ibatis das in etwa so:

Es frägt laut deiner Angabe in der XML die DB ab und holt sich die Spalten. Parallel zur XML hat dir das Tutorial ja gezeigt wie das Transportobjekt "Person" angelegt wird. Wenn du jetzt eine Person aus der Db abfrägst wird die Ergebnistabelle zerlegt und die Werte in ein neu instantiiertes Personenobjekt eingetragen. DB-Verbindungsaufbau und die Sache mit dem Resultset macht iBatis für dich.

Beim einfügen in die DB gehts ähnlich:

Du hast ein Personen-Objekt welches alle Personendaten enthält. iBatis nimmt dieses Objekt, holt sich alle Daten aus dem Objekt und befüllt damit den SQL-String in deiner XML und führt diesen dann aus. Fertig.
D.h. du arbeitest nur noch mit einfachen Objekten und hast den SQL-Teil weit weg vom Code. Und das tolle ist: Du kannst die DB komplett tauschen und auch eine andere Struktur der DB wählen. Einfach die XML anpassen und dein Programm läuft mit der anderen DB und der anderen Struktur (vorrausgesetz in der neuen DB und Struktur sind _irgendwo_ die Infos vorhanden um eine Person zusammenzubauen).

Die Sache mit dem ersten anlegen der Tabellen: Ja, das könntest du in eine eigene Methode auslagern, die direkt nach programmstart und noch vor iBatis das ganze prüft und ggf. die Tabellen erstellt. Danach ist dann aber iBatis dein Kontakt zur DB. D.h. die DB_Connection und die Sachen mit dem Resultset was du zum prüfen und erstellen der Tabellen brauchst bleibt alles in der einen Prüf- und Anleg-Methode und wird NUR DORT und NUR FÜR DIESEN ZWECK benutzt.

- Alex
 

ms

Top Contributor
Das Problem mit dem Anlegen wird wohl sein, dass zwar Tabellen dazukommen können aber die entsprechenden xml-Files und die Objekte natürlich nicht existieren.

ms
 
M

maki

Gast
Das Problem mit dem Anlegen wird wohl sein, dass zwar Tabellen dazukommen können aber die entsprechenden xml-Files und die Objekte natürlich nicht existieren.
Ja, deswegen auch meine Frage, ob er die Tabellen schon beim komilieren kennt, die er abfragen will.

Wenn nicht, ist iBatis nutzos für ihn.
 
T

tuxedo

Gast
?? Aber ich weiß doch vorher mit welchen Tabellen und Daten ich es zu tun habe? Also kann ich ja auch vorher XMLs und Transportobjekte bauen.

Ich denke gemeint war sowas wie bei HSQLDB dass Anfangs die DB noch leer ist und man erst Tabellen anlegen muss um damit zu arbeiten.

Allerdings könnte man auch ein Datenbankgrundgerüst mit der Anwendung mitliefern und spart sich so den Aufwand die Tabellen beim ersten mal mit der Anwendung erstellen zu müssen.

- Alex
 

PollerJava

Top Contributor
es steht in meiner Konfig- XML- Datei z.B:


Code:
<Element type="TrendVariable" 					id="0"				name="KW1_T1_Wasser"> 
		<varID type="initVar" id="0"> 
			<State id="0">		
...	
      		</State>
        </varID>
    </Element>
	<Element type="TrendVariable" 					id="0"				name="KW1_T1_Leistung"> 
		<varID type="initVar" id="0"> 
			<State id="0">
...
      		</State>
        </varID>
    </Element> 
	<Element type="TrendVariable" 					id="0"				name="KW1_T1_Drehzahl"> 
		<varID type="initVar" id="0"> 
			<State id="0">
...
      		</State>
        </varID>
    </Element>

Ich lese zuerst meine Konfig.XML in eine List ein und laufe diese List dann durch und schaue wieviel "Variablen" es gibt und lege eben im oberen Fall 3 Tabellen mit dem namen=... an,





ja, das habe ich soweit jetzt verstanden,
was mir noch unklar ist, ist, wie du schreibst, dass Objekte in die DB gespeichert und von der DB geholt werden,
ich habe in meiner DB aber nur

Code:
stmt = getDBConnection().prepareStatement(String.format("SELECT zeitstempel, wert FROM %s WHERE zeitstempel BETWEEN ? AND ?", dBName));
 
stmt = dBDriver.getDBConnection().prepareStatement(String.format("INSERT INTO %s (Kommen, Gehen, Quit, AlarmNr, Var1, Var2) VALUES ( ?, ?, ?, ?, ?, ?)", tableName));

stmt = dBDriver.getDBConnection().prepareStatement(String.format("UPDATE %s SET Quit = ? WHERE Kommen = ? AND AlarmNr = ? ", tableName));

Ich muss mir das erst ansehen, wie ich das dann der SqlMap übergebe, ich hoffe das funktioniert,

bin momentan beim erstellen der XML- Datei mit dem Tutorum (mit 12 Seiten) von maki, das mit den 9 Seiten von Alex hab ich schon gelesen,

lg
 
T

tuxedo

Gast
Mir scheint du stehst total auf dem Schlauch und hast noch nicht verstanden wozu iBatis und Co. gut ist.

Nochmal im aller Kürze:

iBatis und Co speichern keine Java-Objekte in der DB. diese Tools machen nur ein "mapping". D.h. du kannst Eigenschaften, Daten, Zahlen, Texte, .. aus der DB lesen und sie einem Objekt zuordnen. Beispielsweise "Person".

Magisches Wort ist hierbei "mapping".

- Alex
 

PollerJava

Top Contributor
JA heute ist mir schon vieles klarer aber noch nicht alles,
Dankeschön für Eure Geduld, das ist ein neues Thema für mich,

lg
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
T Zugriff auf Datenbank Allgemeine Java-Themen 1
LucasGlockner Effizienter byte-Zugriff auf ein long[]-Array Allgemeine Java-Themen 8
W Klassen Zugriff auf ein Textfile aus allen Klassen. Allgemeine Java-Themen 2
izoards Zugriff auf gemeinsame Ressource (CSV-File) Allgemeine Java-Themen 3
S Java Zugriff auf Netzwerklaufwerk Allgemeine Java-Themen 1
sascha-sphw Java 9 module Zugriff auf eine resource einer anderen JAR Allgemeine Java-Themen 0
KeexZDeveoper Zugriff auf Methoden vom Server Allgemeine Java-Themen 7
O Zugriff auf mySQL ohne JDBC Allgemeine Java-Themen 3
P Element einer Liste wurde hinzugefügt, aber es gibt keinen Zugriff Allgemeine Java-Themen 2
B Maven Zugriff auf files aus einem kompilierten jar Allgemeine Java-Themen 15
S Zugriff auf jUnit Test Suite Runner-Instanzen innerhalb von Test Classes Allgemeine Java-Themen 7
W Zugriff auf Objektvariablen vs. Übergabe Allgemeine Java-Themen 3
J Zugriff auf erstellte Objekte einer Klasse von einer Klasse ausserhalb Allgemeine Java-Themen 3
Tommy Nightmare HTTP Zugriff auf Internetseite im Loginbereich Allgemeine Java-Themen 5
H Zugriff auf PHP Allgemeine Java-Themen 4
B DB-Zugriff einer Webanwendung funktioniert nicht mit Java 7 Allgemeine Java-Themen 2
M WebService - Zugriff auf Webservice Methode über Browser Allgemeine Java-Themen 1
O JNA Zugriff auf Funktion aus DLL Allgemeine Java-Themen 0
O Zugriff auf Windows Zertifikatstore Allgemeine Java-Themen 2
M Kein Zugriff auf microSD Karten Allgemeine Java-Themen 4
J Zugriff auf IMAP GMail Konto scheitert. Allgemeine Java-Themen 2
P Frontend- Zugriff auf WS- Backend Allgemeine Java-Themen 0
U Zugriff auf Datei sperren Allgemeine Java-Themen 5
N Best Practice Semi-Synchronized Zugriff Allgemeine Java-Themen 0
C Zugriff auf Event felder Allgemeine Java-Themen 0
M Threads synchroner Zugriff (add/delete/read) auf eine Liste Allgemeine Java-Themen 6
F Zugriff Verweigert bei Kopieroperation? Allgemeine Java-Themen 4
T JNI: kein Zugriff auf VM in Callback-Methode eines Windows-Hooks Allgemeine Java-Themen 3
S Dynamischer Zugriff Allgemeine Java-Themen 4
Minonos Einem Programm Zugriff auf bestimmte Ordner geben Allgemeine Java-Themen 5
E Zugriff auf Dateien im Filesystem überwachen Allgemeine Java-Themen 5
H Programierstil: static - Zugriff vs. Staticzugriff Allgemeine Java-Themen 24
V Zugriff auf den Objekterzeuger? Allgemeine Java-Themen 4
M Zugriff zweier Threads auf diesselbe Methode Allgemeine Java-Themen 16
B Zugriff auf eine HashMap Allgemeine Java-Themen 4
B JApplet Zugriff auf Local Storage des Browser? Allgemeine Java-Themen 2
D Zugriff auf Array-Liste Allgemeine Java-Themen 19
M gleichzeitiger Zugriff auf eine Textdatei Allgemeine Java-Themen 6
D Eclipse Kein Zugriff auf Inhalt einer referenzierten .jar Allgemeine Java-Themen 5
B synchronisierter zugriff auf Objekt Allgemeine Java-Themen 6
nutellastulle Zugriff, Übergabe, Bearbeitung und Ausgabe von Jlist Allgemeine Java-Themen 6
U Große Liste von Strings mit indiziertem Zugriff Allgemeine Java-Themen 31
J XML Element Zugriff Allgemeine Java-Themen 4
P Daten kopieren mit nio - Zugriff verweigert Allgemeine Java-Themen 8
M Klassen Zugriff auf getMethode ohne Klasse zu erzeugen Allgemeine Java-Themen 6
A Input/Output Applet-Zugriff auf PHP-Schnittstelle (externer Server) Allgemeine Java-Themen 22
H Vererbung Abgeleitete Klassen und Zugriff Allgemeine Java-Themen 2
C Probleme mit dem Zugriff auf private Methode per reflection Allgemeine Java-Themen 2
J Zugriff auf Poker-Client Fenster Allgemeine Java-Themen 14
C Zugriff auf private Methode per reflection geht nicht mehr Allgemeine Java-Themen 3
S Zugriff auf innere Klasse Allgemeine Java-Themen 3
D Kein Zugriff auf WebService ausser localhost Allgemeine Java-Themen 4
Sonecc Zugriff auf Class File einer anderen Jar während der Laufzeit Allgemeine Java-Themen 2
J Zugriff auf Dateien auf einem shared Folder? Allgemeine Java-Themen 3
H Zugriff auf VBA in Java Allgemeine Java-Themen 2
Haave Audio Device Unavailable: Kein gleichzeitiger Zugriff auf Soundsystem möglich Allgemeine Java-Themen 7
G Letzter Zugriff auf Datei Allgemeine Java-Themen 5
C java.io.FileNotFoundException: (Zugriff verweigert) Allgemeine Java-Themen 14
O Zugriff auf Serielle Schnittstelle - Keine Ports gefunden. Allgemeine Java-Themen 8
C Webstart: Zugriff auf lokale Dateien? Allgemeine Java-Themen 2
X Zugriff auf ComboBoxen in Hauptklasse von zweiter Klasse aus Allgemeine Java-Themen 8
J Zugriff auf gemeinsame Funktionen Allgemeine Java-Themen 4
Airwolf89 Zugriff auf ArrayList<ArrayList> Allgemeine Java-Themen 3
Airwolf89 Zugriff auf Werte in ArrayList<ArrayList> Allgemeine Java-Themen 4
T Zugriff zwischen Klassen für repaint Allgemeine Java-Themen 7
N Zugriff auf eine Referenzvar. Allgemeine Java-Themen 3
S Zugriff auf Klasse Allgemeine Java-Themen 4
Meldanor Mehrdimensionale Arrays : Zugriff auf n-tes Array Allgemeine Java-Themen 5
E JNA:Zugriff auf Common-Block von Fortran bzw. Struct in C Allgemeine Java-Themen 2
T Zugriff auf Singleton verkürzen - Namespaces?? Allgemeine Java-Themen 20
L Zugriff auf ein Objekt mit mehreren Threads Allgemeine Java-Themen 11
Airwolf89 dynamischer Zugriff auf Variablen/ Objekte Allgemeine Java-Themen 4
S Zugriff auf einzelne Bildpunkte Allgemeine Java-Themen 3
D Referenzen weiterreichen vs. statischer Zugriff Allgemeine Java-Themen 3
V Zugriff auf Default-Package? Allgemeine Java-Themen 6
P RegeEx-Problem: Zugriff auf group Allgemeine Java-Themen 2
M Zugriff auf Parallel-Schnittstelle Allgemeine Java-Themen 2
B Zugriff mit einem Applet auf den Datenträger Allgemeine Java-Themen 11
S Innere Klasse: Zugriff auf äußere Variable Allgemeine Java-Themen 5
I Zugriff auf Daten Allgemeine Java-Themen 5
T Zugriff per Reflection o.ä. möglich? Allgemeine Java-Themen 18
D Zugriff auf Windows Dienste Allgemeine Java-Themen 7
G Zugriff auf Memberclasses einer geladenen Class-Datei Allgemeine Java-Themen 2
I Gleichzeitiger zugriff auf ein Long über Threads Allgemeine Java-Themen 2
P Wieso HashMap-Zugriff mit Object, statt mit MyObject? Allgemeine Java-Themen 12
J Kein Zugriff auf Klassen im Default Package Allgemeine Java-Themen 8
M Paralleler Zugriff auf statische Methode Allgemeine Java-Themen 5
S Zugriff auf unterschiedliche JREs Allgemeine Java-Themen 7
M "Unzulässiger Zugriff auf einen Speicherbereich" Allgemeine Java-Themen 7
A Zugriff auf Parallelport nur über Eclipse nicht über .jar ! Allgemeine Java-Themen 12
G Zugriff auf ein sama share Allgemeine Java-Themen 8
J Java zugriff auf Exchange Server Allgemeine Java-Themen 10
D eclipse: Zugriff auf Ordner per code Allgemeine Java-Themen 4
O Konkurrierender Zugriff auf Log-Datei mit Log4J Allgemeine Java-Themen 11
Caracasa [Threads] Gleichzeitiger Zugriff auf eine LinkedList Allgemeine Java-Themen 9
L Zugriff auf Objekt das sich in einer Liste befindet Allgemeine Java-Themen 2
J Zugriff auf den Namen einer Variablen Allgemeine Java-Themen 7
J Zugriff auf Map in anderer Klasse Allgemeine Java-Themen 2
J Endlosschleife durch wechselseitigen Zugriff zweier Klassen? Allgemeine Java-Themen 2
F Zugriff auf lokalen Rechner wer weiss Rat ? Allgemeine Java-Themen 16

Ähnliche Java Themen

Neue Themen


Oben