# Datensätze aus DB in TextFeld ausgeben



## Guest (14. Aug 2007)

Hallo zusammen,

Ich hab ein Problem mit meinem Programm. In meiner GUI sind Textfelder, in denen bei Programmstart die Daten des ersten Datensatzes aus einer DB stehen sollen.
Weiter sollen die Textfelder dazu dienen, den Inhalt aus der Datenbank ändern zu können.

Mein Problem dabei ist, dass ich die einzelnen Datensätze nicht voneinander unterscheiden kann.
Im ResultSet werden ja alle Datensätze einer Tabelle gespeichert, aber es soll ja immer nur einer davon angezeigt werden. Per Button sollen dann zwischen den Datensätzen, vor und zurück, geschaltet werden.

Könnt ihr mir dabei helfen?
Habt ihr etwaige Lösungsvorschläge?

Bisher versuche ich es so:
- eine Klasse, die für die Spalten der Tabelle aus der DB Variablen bereithält
- das ResultSet weisst (durch eine for-Schleife) einem Objekt der Klasse den Datensatz zu
- die Objekte, die aus der for-Schleife resultieren, werden einer ArrayList hinzugefügt
- via den Indexnummern der ArrayList weise ich den Textfeldern die einzelnen Datensätze zu

nur leider klappt das noch nicht so richtig.

Erhalte für meine SQL Abfrage eine NullPointerException....?!

Bin auch offen für weitere, vllt einfachere Vorschläge!

Liebe Grüße, 

Marie


----------



## jPat (14. Aug 2007)

wie sieht deine SQL-Abfrage aus?


----------



## Marie Curie (14. Aug 2007)

SELECT * FROM KUNDE

Verbindung stell ich über JDBC:ODBC Bridge her
Tabelle is auch in DB vorhanden und heisst so


----------



## MarcoBehnke (14. Aug 2007)

um Deine Datensätze voneinander unterscheiden zu können, reicht ja ein eindeutiges Feld über die Tabelle, eine künstliche ID quasi

Da Du die mitausliest, kannst Du anhand derer auch später die Updates machen.

Über welchem Statement bekommst du die NullPointerException? Codeblock?


----------



## Marie Curie (14. Aug 2007)

hab die DB Verbindung in ner eigenen Klasse.
Über eine Instanz der Klasse will ich aus der GUI-Klasse Verbindung aufnehmen:


```
ResultSet ergebnis  = einZugriff.DBlesen("SELECT * FROM KUNDE");
```

die Methode DBlesen erwartet nen String, den SQL Befehl und liefert ein ResultSet zurück
genau in der Zeile fliegt die Exception


----------



## MarcoBehnke (14. Aug 2007)

poste doch bitte einmal den Exceptionblock,  der Stacktrace hilft weiter.


----------



## Marie Curie (14. Aug 2007)

Hab die Exception bisher mit getMessage() ausgegeben
durch StackTrace erhalte ich aber die selbe Nachricht.... das sollte doch eigentlich nicht so sein?!

Ich schick dir mal die Methode und die Fehlermeldung



> Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
> at graphics.GUI_NetBeans.leseFormular(GUI_NetBeans.java:409)
> at graphics.GUI_NetBeans.<init>(GUI_NetBeans.java:16)
> at graphics.GUI_NetBeans$4.run(GUI_NetBeans.java:441)
> ...




```
public void leseFormular() throws SQLException{
    	
    	    	    	
    	try {

			ResultSet ergebnis  = einZugriff.DBlesen("SELECT * FROM KUNDE");

			for(int i = 0; i < ergebnis.getRow(); i++){
				
				DBDatensatz einDatensatz = new DBDatensatz();
				
				einDatensatz.setID(i);
				
				einDatensatz.setkdNr(ergebnis.getInt("KdNr"));
				einDatensatz.setName(ergebnis.getString("Name"));
				einDatensatz.setStrasse(ergebnis.getString("Strasse"));
				einDatensatz.setHausNr(ergebnis.getString("HausNr"));
				einDatensatz.setPlz(ergebnis.getInt("Plz"));
				einDatensatz.setOrt(ergebnis.getString("Ort"));
				einDatensatz.setLand(ergebnis.getString("Land"));
				einDatensatz.setTel(ergebnis.getString("Telefon"));
				einDatensatz.setFax(ergebnis.getString("Telefax"));
				
				ArrayList<Object> datensaetze = new ArrayList<Object>();
				datensaetze.add(einDatensatz);				
			}
		} 
    	catch (SQLException e) {
			e.printStackTrace();
		}
    	
    }
```

Liebe Grüße


----------



## DocMcFly (14. Aug 2007)

```
ArrayList<Object> datensaetze = new ArrayList<Object>();
            datensaetze.add(einDatensatz);
```

Ich denke das darf nicht sein... Du setzt in der Schleife jedesmal die ArrayListe neu. Deshalb hat die auch nur ein Element. 

Versuch es mal so:


```
public void leseFormular() throws SQLException{
       
       ArrayList<Object> datensaetze = new ArrayList<Object>();          
       try {

         ResultSet ergebnis  = einZugriff.DBlesen("SELECT * FROM KUNDE");

         for(int i = 0; i < ergebnis.getRow(); i++){
            
            DBDatensatz einDatensatz = new DBDatensatz();
            
            einDatensatz.setID(i);
            
            einDatensatz.setkdNr(ergebnis.getInt("KdNr"));
            einDatensatz.setName(ergebnis.getString("Name"));
            einDatensatz.setStrasse(ergebnis.getString("Strasse"));
            einDatensatz.setHausNr(ergebnis.getString("HausNr"));
            einDatensatz.setPlz(ergebnis.getInt("Plz"));
            einDatensatz.setOrt(ergebnis.getString("Ort"));
            einDatensatz.setLand(ergebnis.getString("Land"));
            einDatensatz.setTel(ergebnis.getString("Telefon"));
            einDatensatz.setFax(ergebnis.getString("Telefax"));
            
           
            datensaetze.add(einDatensatz);            
         }
      }
       catch (SQLException e) {
         e.printStackTrace();
      }
       
    }
```

Stellt sich mir nur die Frage, was machst du mit der ArrayListe  ? Diese verlässt ja nie die Methode. Versuchst Du auf "this.datensaetze" zuzugreifen? Dann ist die ja immer noch null, weil sie nur lokal in der Methode gesetzt wurde. 

Dann tausche mal die Zeile 

```
ArrayList<Object> datensaetze = new ArrayList<Object>();
```

gegen:


```
this.datensaetze = new ArrayList<Object>();
```

oder besser gib "datensaetze" als return zurück...


Gruß Clemens


----------



## Marie Curie (15. Aug 2007)

DocMcFly hat gesagt.:
			
		

> ```
> ArrayList<Object> datensaetze = new ArrayList<Object>();
> datensaetze.add(einDatensatz);
> ```
> ...



Stimmt, der Fehler is mir noch gar nich aufgefallen...  danke 
aber das behebt leider die Exception nicht, diese wird ja immer noch in der Zeile mit dem SQL Befehl geworfen  ???:L




> oder besser gib "datensaetze" als return zurück...



hab ich gemacht, dazu hab ich aber noch ne kleine Frage:
ich hab die Methode mit try/catch umgeben, aber wenn ich die Methode zu ner getter-Methode bastel, 
nimmt der Compiler mein return-Statement nich an, weil es im try-Block steckt und nicht außerhalb...
Wenn ich das return-Statement außerhalb des try-Blocks aufrufe, kennt er die ArrayList nich

...wie kann ich das so hinbiegen?

einfach die ArrayList vor dem try/catch initialisieren?

Liebe Grüße und vielen Dank 
Marie


----------



## Marie Curie (15. Aug 2007)

Hallo nochmal 

ich hab es jetzt folgendermaßen gemacht:


```
public ArrayList leseFormular() throws SQLException{

    	ArrayList<Object> datensaetze = new ArrayList<Object>();
    	try{
    		einZugriff = new DBZugriff();
		ResultSet ergebnis  = einZugriff.DBlesen("SELECT * FROM KUNDE");
						
			for(int i = 0; i < ergebnis.getRow(); i++){
				
				DBDatensatz einDatensatz = new DBDatensatz();
				
				einDatensatz.setID(i);
				
				einDatensatz.setkdNr(ergebnis.getInt("KdNr"));
				einDatensatz.setName(ergebnis.getString("Name"));
				einDatensatz.setStrasse(ergebnis.getString("Strasse"));
				einDatensatz.setHausNr(ergebnis.getString("HausNr"));
				einDatensatz.setPlz(ergebnis.getInt("Plz"));
				einDatensatz.setOrt(ergebnis.getString("Ort"));
				einDatensatz.setLand(ergebnis.getString("Land"));
				einDatensatz.setTel(ergebnis.getString("Telefon"));
				einDatensatz.setFax(ergebnis.getString("Telefax"));
								
				datensaetze.add(einDatensatz);	
				
			}
		}
		catch(SQLException e){
				e.printStackTrace();
		}
    	
		if(datensaetze == null){
			System.out.println("Der Datensatz ist leer");
    	}
    	return datensaetze;
		
    }
```

Soweit passt das auch...hab mir das ResultSet mal ausgeben lassen:



> sun.jdbc.odbc.JdbcOdbcResultSet@19f953d



Was bedeutet das?
Durch dieses ResultSet erhalte ich ne Exception bei der Instanzierung der Schleife
--> durch das getRow()
(klar, das RS besteht ja auch nicht aus Zeilen...)

Ich schicke mal die Methode für das Lesen der Datenbank

```
public ResultSet DBlesen(String befehl) throws SQLException{

		ResultSet dasErgebnis = null;
		
		try {
				statement = connection.createStatement();
				result = statement.executeQuery(befehl);
			
				dasErgebnis = result;
			} 
		catch (SQLException ex1) {
				System.out.println("Es ist ein Fehler aufgetreten: " + ex1.getMessage());
			}
		System.out.println(dasErgebnis);
		return dasErgebnis;
				
	}
```

Verbindung stell ich folgender Maßen her:

```
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver").newInstance();
connection = DriverManager.getConnection("jdbc:odbc:odbc2access");
```

Bin für jede Hilfe dankbar!

Liebe Grüße,
Marie


----------



## DocMcFly (15. Aug 2007)

mmmh ... also wenn ich das richtig verstehe, willst Du das so haben (s.u.)

*Anmerkungen zum Code:*
Die Liste muss außerhalb des try/catch-Block deklariert werden. Dann steht diese innerhalb des try/catch-Blocks zur Verfügung und ist danach auch noch da fürs "returnen" da. 

*Zu Deiner NullPointerException: *
Hast mal überprüft, ob "ergebnis" nicht vielleicht null ist, wenn das "SELECT * FROM KUNDE" nix zurück wirft? 

*Noch ein Tipp:* 
Schau Dir mal Apache DbUtils an ( http://commons.apache.org/dbutils/ ) Mit dem BeanHandler spart man sich die ganze setter-Aufrufe und der BeanListHandler liefert die gleich die Liste aller Beans   Genau das was Du hier programmierst in 3 Zeilen  

Gruß Clemens 




```
public List leseFormular() throws SQLException {

    ArrayList<Object> datensaetze = new ArrayList<Object>();
    try {

      ResultSet ergebnis = einZugriff.DBlesen("SELECT * FROM KUNDE");

      for (int i = 0; i < ergebnis.getRow(); i++) {

        DBDatensatz einDatensatz = new DBDatensatz();

        einDatensatz.setID(i);

        einDatensatz.setkdNr(ergebnis.getInt("KdNr"));
        einDatensatz.setName(ergebnis.getString("Name"));
        einDatensatz.setStrasse(ergebnis.getString("Strasse"));
        einDatensatz.setHausNr(ergebnis.getString("HausNr"));
        einDatensatz.setPlz(ergebnis.getInt("Plz"));
        einDatensatz.setOrt(ergebnis.getString("Ort"));
        einDatensatz.setLand(ergebnis.getString("Land"));
        einDatensatz.setTel(ergebnis.getString("Telefon"));
        einDatensatz.setFax(ergebnis.getString("Telefax"));


        datensaetze.add(einDatensatz);
      }
    } catch (SQLException e) {
      e.printStackTrace();
    }
    return datensaetze;
  }
```


----------



## DocMcFly (15. Aug 2007)

Da hab ich wohl fast zeitgleich geschrieben: Den Eintrag von Dir 10.41Uhr kannte ich noch nicht...

Also mal sehen... denke ich hab's gefunden:

Hab mal hier nach gesehen:
http://www.galileocomputing.de/open...20_006.htm#mj669aa7594d9ad71d3aa05ec6b797fce0
(Kapitel 20.6.2)

versuche es doch mal so... wie die es beschrieben haben.

Ach ja... noch was... Hab mich wohl unklar ausgedrückt:

Diese Abfrage ist sinnlos... denn Du erzeugst ja in der Methode ganz frisch die ArrayList "datensaetze".

```
if(datensaetze == null){
         System.out.println("Der Datensatz ist leer");
       }
```

Was ich meinte, war dass Du das ResultSet auf null prüfst.

```
if(ergebnis  != null){
  try{ .... }catch(SQLException e){
            e.printStackTrace();
      } 
}
```


----------



## DocMcFly (15. Aug 2007)

> Soweit passt das auch...hab mir das ResultSet mal ausgeben lassen:
> 
> 
> 
> > sun.jdbc.odbc.JdbcOdbcResultSet@19f953d



Das bedeutet nur: es ist nicht null sondern eine Instanz von "sun.jdbc.odbc.JdbcOdbcResultSet" in der Variable.  "19f953d" ist ein eindeutiger HashCode der Instanz. (Glaub ich ) :roll: 

Gruß Clemens


----------



## Marie Curie (16. Aug 2007)

DocMcFly hat gesagt.:
			
		

> > Soweit passt das auch...hab mir das ResultSet mal ausgeben lassen:
> >
> >
> >
> ...



Aber müsste ich hier nich eigentlich den Inhalt des ResultSets ausgegeben bekommen?
Also etwas in der Richtung  "KdNr 1111, Name Müller"

Wenn ich den Inhalt des RS in einem Textfeld ausgeben will komm ich ja damit nich besonders weit...

Liebe Grüße


----------



## Marie Curie (16. Aug 2007)

hat sich soeben erledigt


----------



## DocMcFly (16. Aug 2007)

EOT ?


----------



## Marie Curie (16. Aug 2007)

So.. also ich poste mal wie ichs jetzt gemacht hab, es funktioniert schon teilweise.


Diese Methode führt die Anfrage in der DB durch und speichert die Datensätze in einer ArrayList:

```
public ArrayList DBlesen() throws SQLException{

		try 
		{
				String befehl = "SELECT * FROM KUNDE";
				statement = connection.createStatement();
				result = statement.executeQuery(befehl);
				
			   	ArrayList<Object> datensaetze = new ArrayList<Object>();

			   	if(result != null){
			    			
			    			System.out.println("RS hat Next: " + result.next());
			    			
			    			while(result.next()){	
			    				
			    				DBDatensatz einDatensatz = new DBDatensatz();
			    								
			    				einDatensatz.setkdNr(result.getInt(1));
			    				einDatensatz.setName(result.getString(2));
			    				einDatensatz.setStrasse(result.getString(3));
			    				einDatensatz.setHausNr(result.getString(4));
			    				einDatensatz.setPlz(result.getInt(5));
			    				einDatensatz.setOrt(result.getString(6));
			    				einDatensatz.setLand(result.getString(7));
			    				einDatensatz.setTel(result.getString(8));
			    				einDatensatz.setFax(result.getString(9));
											
			    				datensaetze.add(einDatensatz);	
			    			}
			    			System.out.println("Anzahl in AL: " + datensaetze.size());
			    		}
				return datensaetze;
		} 
		
		catch (SQLException ex1) 
		{
				System.out.println("Es ist ein Fehler aufgetreten: " + ex1.getMessage());
		}
		
		return null;	
	}
```

Jetzt hab ich aber immer noch ein (kleines?) Problem:
In der Tabelle der DB, aus der ich die Daten nehme, sind insgesamt 5 Datensätze. Die Array List besteht aber nur aus 4 Elementen. 
Der erste Datensatz aus der DB ist einfach "verschwunden". Liegt es an der Schleife (vllt durch next()?) ?

Liebe Grüße
Marie



> EOT?


was meinst du?


----------



## DocMcFly (16. Aug 2007)

Jepp, das kann an dem next() liegen. Denn der erste ist ja bereits vorhanden. So spring next() gleich zum 2. Datensatz.  

Nimm doch für so was, statt einer while-Schleife eine do-while-Schleife.

Da steht dann das next() am Ende. Ungefähr so:


```
do {   
  DBDatensatz einDatensatz = new DBDatensatz();

  einDatensatz.setkdNr(result.getInt(1));
  einDatensatz.setName(result.getString(2));
  einDatensatz.setStrasse(result.getString(3));
  einDatensatz.setHausNr(result.getString(4));
  einDatensatz.setPlz(result.getInt(5));
  einDatensatz.setOrt(result.getString(6));
  einDatensatz.setLand(result.getString(7));
  einDatensatz.setTel(result.getString(8));
  einDatensatz.setFax(result.getString(9));
                                 
  datensaetze.add(einDatensatz);   
} while(result.next());
```


Gruß Clemens 

PS:

EOT - End Of Thread :

EOT? = Wollte wissen, ob das Thema abgeschlossen ist.


----------



## Marie Curie (16. Aug 2007)

Die do-while Schleife werde ich auf jeden Fall noch ausprobieren.

Wollte durch "einbauen" eines Counters prüfen, wie oft die Schleife durchlaufen wird. Kurioserweise funktioniert es seitdem.
Deswegen bleib ich vorerst mal bei der while-Schleife. Durch kurzes Ausprobieren der do-while Schleife hagelte es wieder ne Exceptions, die dadurch in anderen Methoden entstehen... 

Zu deiner Frage, ja der Thread ist beendet 

Danke für deine tatkräftige Unterstützung, warst mir ne sehr große Hilfe  :applaus: 

Liebe Grüße,
Marie


----------

