# Aufbau einer DB-Klasse



## Hannes23 (22. Okt 2005)

Hallo,

ich bastle gerade an einer Datenkbankklasse zum Zugriff auf eine MySQL-Datenbank, sie sieht folgendermaßen aus:


```
public class db {
  
      public static void opendb( String host, String dbName, String dbUser, String dbPwd ) {
    
        String port = "3306";
        String dbType = "mysql";

        String myDrivers =
            "com.mysql.jdbc.Driver" +
            ":" +
            "oracle.jdbc.driver.OracleDriver";

        System.setProperty(
            "jdbc.drivers",
            myDrivers
        );

     
        try {
            Class.forName(
                "com.mysql.jdbc.Driver"
            );
        } catch ( Exception ex ) {
            System.err.print( ex );
            System.exit( 1 );
        }


        // Verbindung zur DB aufbauen
        Connection conn = null;

        String uri = "jdbc:" + dbType + "://" +
            host + ":" + port + "/" +
            dbName;
        try {
            conn = DriverManager.getConnection(
                uri,
                dbUser,
                dbPwd
            );
            
        } catch ( Exception ex ) {
            System.err.print( ex );
            System.exit( 1 );
        } 
        System.exit( 0 );
	
    }
    
    
    
    
    
    
    
    public void sql_query() {
	   
	... [Abfragen]
	
    }
    
    
    
    public void close_db() {
	     if ( conn != null ) {
                try {
                    conn.close();
                } catch ( Exception ign ) {}
            }
    }
}
```

Meine Probleme/Fragen:

-Würdet an diesem Herangehen etwas als grundsätzlich falsch bezeichnen, sprich ist etwas dabei, das man auf keinen Fall so machen sollte?

-Ich habe eine Funktion zum Aufbau der Verbindung, eine Funktion für Abfragen und eine zum Beenden der Verbindung. Ich wollte zu Beginn des Programms die Funktion OpenDB aufrufen, dann wenn ich Abfragen brauche die Funktion sql_query und beim Schließen des Programms close_db(). Dabei hab ich natürlich das Problem, dass das Connectionobjekt conn in der openDB erstellt wird und ich somit in der sql_query und in der close_db nicht darauf zugreifen kann, was aber nötig ist. Wie kann ich das umgehen?

Danke, Hannes


----------



## Exceptionist (22. Okt 2005)

wir haben in unserem unterricht eine klasse DBTool geschrieben, die kannste in einem extra-package reinpacken.
den qelcode dafür siehst du hier:

```
package util;
import java.sql.*;
import java.util.*;
public class DBTool {
    private static DBTool tool;
    private String driver ="org.gjt.mm.mysql.Driver";
    private String verbindung ="jdbc:mysql://localhost:3306/test";
    private String user="root";
    private String password="welcome";
    private Connection con;
    private Vector vHeader = new Vector();
    private PreparedStatement psInsert ;
    private PreparedStatement psDelete ;
    private DBTool() {
        this("org.gjt.mm.mysql.Driver", "jdbc:mysql://localhost:3306/test", "root","welcome");
    }
    private DBTool(String driver, String verbindung, String user, String password) {
        this.driver = driver;
        this.verbindung=verbindung;
        this.user=user;
        this.password=password;
        
        try {
            Class.forName(driver);
            con = DriverManager.getConnection(verbindung,user,password);
            psInsert = con.prepareStatement("INSERT INTO tab_mitarbeiter values(?,?,?)");
            psDelete = con.prepareStatement("DELETE FROM  tab_mitarbeiter where vn = ? AND nn = ?");
        } catch (Exception e) {
            System.out.println("Problem in DBTool Konstuktor" + e);
            System.exit(0);
        }
        
    }
    public static DBTool getInstance() {
        // wenn das Objekt noch nicht erzeugt werde
        if (tool == null) {
            tool = new DBTool();
        }
        return tool ;
    }
    public Vector getHeader() {
        if (vHeader.size() ==  0){
              getAllRecords();
        }
        return vHeader;
    }
    public Vector getAllRecords() {
        Vector megaVector = new Vector();
        try {
            Statement stmt = con.createStatement();
            
            ResultSet rs = stmt.executeQuery("SELECT * FROM tab_mitarbeiter");
            ResultSetMetaData rsmd = rs.getMetaData();
            
            int count = rsmd.getColumnCount();
            vHeader.clear();
            for (int i = 1; i<= count;i++) {
                    
                        vHeader.add(rsmd.getColumnLabel(i));
                    }
            // Schleife die Satz für Satz durch RS läuft
            while (rs.next()) {
                Vector satzVector =new Vector();
                // Spaltenschleife
                for (int i = 1; i<= count;i++) 
                    {
                        satzVector.add(rs.getString(i));
                    }
                    megaVector.add(satzVector);
                
            }
            
           
        } catch (SQLException se ) {
            System.out.println("Problem in getAllRecords() " +se);
        }
         return megaVector;
    } 
    public void loeschen(String vn, String nn) {
        try {
        psDelete.setString(1, vn);
        psDelete.setString (2,nn);
        psDelete.executeUpdate();
        } catch (SQLException se )
        {
            System.out.println(" Problem beim loeschen" + se);
        }
    }
    public void einfuegen(String vn, String nn, double gehalt) throws SQLException 
     
    {
    try {
        // hier ein bereits vorhandenes PreparedStatment
        psInsert.setString(1,vn);
        psInsert.setString(2, nn);
        psInsert.setDouble(3, gehalt);
        psInsert.executeUpdate();
    } catch (SQLException se ) {
        System.out.println("Probleme in einfuegen ");
        throw se;
    }
    }
    
    public static void main(String [] args) {
       DBTool tool = DBTool.getInstance();
       Vector inhalt = tool.getAllRecords();
       System.out.println(inhalt );
       Vector header = tool.getHeader();
       System.out.println(header );
       inhalt = tool.getAllRecords();
    }
}
```

ich hoffe es ist nicht schlimm, dass ich hier auf bestimte tabellen verweise 
und nicht mit stellvetretenden ausdrücken gearbeitet hab...

bei fragen zur datenbank, die hinter dieser klasse steckt, stehe ich gerne zur verfügung.
ich hoffe mal der rest erklärt sich von selbst.


----------



## Hannes23 (23. Okt 2005)

Dankeschön, ist auch schon mal sehr hilfreich!


----------



## Hannes23 (23. Okt 2005)

aber wie machst Du das beispielsweise, wenn diese Datenbankklasse in einer eigenen Datei ist und z.B. eine Datei Hauptprogramm.java dann darauf zugreifen soll? Dann bekomme ich beim Kompillieren des "Hauptprogramms" mit dem Aufruf 


```
DBTool tool = DBTool.getInstance();
       Vector inhalt = tool.getAllRecords();
       System.out.println(inhalt );
```

im "Hauptprogramm" nämlich folgenden Fehler:


```
Hauptprogramm.java:13: cannot resolve symbol
symbol  : class Vector
location: class Hauptprogramm
       Vector inhalt = tool.getAllRecords();
       ^
```

Oder hast Du das irgendwie über das package gelöst??


----------



## Guest (24. Okt 2005)

ich geb dir jetzt nur kurze informationen, denn dann ist dein lern-effekt grösser und ich kann dir helfen UND für meine zertifizierung pauken...

also:

```
DBTool tool = DBTool.getInstance(); 
       Vector inhalt = tool.getAllRecords(); 
       System.out.println(inhalt );
```
ist wichtig, damit die klasse DBTool als Singleton läuft und das Objekt dementsprechend auch wirklich nur 1 mal existiert.

dann musste das Package, in dem du das tool hast, in dein hauptprogramm importieren und das tool als Attribut bekannt machen.

```
import util.*;

bla bla bla (String []args){

private DBTool tool;
...
usw
```

was ein Vector ist weisst du doch bestimmt oder nicht??
den musste nämlich mit ner doppelten FOR-Schleife auslesen... es sei denn du hast lust den kompletten tabellen-inhalt auf einmal anzuzeigen
das system.out.println(inhalt); ist lediglich eine kontrolle gewesen.

wenn dir das hier noch nicht geholfen haben sollte, musste leider nochmal bescheid geben.


----------



## Exceptionist (24. Okt 2005)

ups... sorry hatte vergessen mich einzuloggen...soooorryy


----------



## Bleiglanz (24. Okt 2005)

wo sind eigentlich die .close() Methoden im DBTool?


----------



## Exceptionist (24. Okt 2005)

> wo sind eigentlich die .close() Methoden im DBTool?



wir haben das Tool hauptsächlich in serverseitigen anwendungen benutzt und im hauptprogramm bzw im hauptservlet
session.invalidate(); benutzt, denn ohne gültige session hatten wir kein DBTool zur verfügung.

also wir hatten auch noch keine probleme damit.
unser dozent sagte mal irgendwann, dass wir hier keine close-methode bräuchten, es geschiehe implizit, das das close(); aufgerufen wird!


hier sind nochmal 5 Schritte, wie das mit ner datenbank-anbindung klappt!!!
diesmal etwas allgemeiner!!!

```
import java.sql.*; 
  public class FuenfSchritte {
    public static void main(String[] args) throws Exception {

   1   Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
        Connection c = DriverManager.getConnection("jdbc:odbc:Kurse");


   2   Statement s = c.createStatement();


   3   s.execute("SELECT * FROM Personen WHERE nachname LIKE 'K%'");
        ResultSet r = s.getResultSet();

   4   while(r.next())
        System.out.println(r.getString("vorname")+" "+r.getString("nachname"));

   5   c.close();
    }
  }
```

Die Durchnummerierung solltet ihr natürlich beim programmieren auskommentieren oder ganz weglassen


----------



## Bleiglanz (24. Okt 2005)

> wir haben das Tool hauptsächlich in serverseitigen anwendungen benutzt und im hauptprogramm bzw im hauptservlet
> session.invalidate(); benutzt, denn ohne gültige session hatten wir kein DBTool zur verfügung.


drum auch das System.exit(0), damit der Server gleich sauber beendet wird 



> also wir hatten auch noch keine probleme damit.
> unser dozent sagte mal irgendwann, dass wir hier keine close-methode bräuchten, es geschiehe implizit, das das close(); aufgerufen wird!


scheint ein Zertifikatslehrgang zu sein


----------



## Exceptionist (24. Okt 2005)

es ist ein zertifizierungslehrgang!

ich bin momentan in der Bonner Akademie und mache einen Lehrgang zum "Sun Certified Java Programmer"
Grundwissen in Sachen Oracle9i (SQL) ist auch mit dabei.
jedoch nutzen wir für kleinere projekte im bereich java eine MySQL-datenbank.


das hatte zur folge, dass wir einfach mal ein DBTool geschrieben haben....

und bei mir hat immer alles einwandfrei funktioniert.
letzte prüfung hab ich mit 100% bestanden


----------



## Bleiglanz (24. Okt 2005)

schon klar



> und bei mir hat immer alles einwandfrei funktioniert.


das hört man leider viel zu oft von Programmierern deren Programm gerade einmal NICHT funktioniert 

ist zwar off-topic: vHeader ist ein potentielles Speicherleck und nicht threadsafe, würde mal sagen dass das DBTool für serverseitige Apps nicht wirklich geeignet ist...


----------

