# MySQL Connection Global



## powerLAN (14. Mrz 2016)

Guten Tag,
Ich würde folgende Methode, die ich in jedem jDialog geschrieben habe global für alle in eine Klasse setzen und dann in jedem jDialog abrufen können, so dass ich nicht für jeden jDialog eine eigene Verbindung erstelle.
Hoffe ihr könnt verstehen was ich meine.

MfG


```
public Registrieren(Window parent, boolean modal)
    {
        initComponents();
        systemConnection();
    }
   
    //Connection zu der MySQL Datenbank
    public void systemConnection()
    {
        try
        {
            Class.forName("com.mysql.jdbc.Driver");
            con = DriverManager.getConnection("jdbc:mysql://MySQLServer/Datenbank","benutzername","pw");
            stat = con.createStatement();
        } 
        catch (Exception e) 
        {
            JOptionPane.showMessageDialog(null,"Verbindung zur MySQL Datenbank konnte nicht hergestellt werden.");
        }
    }
```
Hier oben mal der Code aus einem jDialog.
So habe ich das in jedem anderen jDialog auch gemacht, aber wie gesagt, möchte ich das global machen, so dass ich nicht immer eine neue Verbindung aufbaue.


----------



## Jardcore (14. Mrz 2016)

Also möchtest du das mit jedem Öffnen einen Dialoges die gleiche Verbindung aufgebaut wird, oder möchtest du das deine Datenbankverbindung einfach beim Start deines Programmes einmal ausgeführt wird?

Ferner solltest du die GUI also die Dialoge und Fenster von deine Logik, dem Verbinden mit der Datenbank, möglichst trennen.

| GUI Klasse | --- verarbeite Klick --->| Logik Klasse | --- verbinden mit Datenbank


----------



## Joose (14. Mrz 2016)

Du könntest eine eigene Klasse schreiben, welche sich um die Datenbankverbindung und Zugriffe kümmert.
Dann bräuchtest du nur ein Objekt dieser Klasse erstellen.

Auch sollte eine Verbindung nur solange offen sein wie sie gebraucht wird, nicht mit öffnen/schließen eines Fensters.

Anmerkung: Generell sollte man UI und Logik Code trennen zum Beispiel anhand einer sauberen Schichtenarchitektur, oder wenns kleiner sein soll hilft auch MVC


----------



## powerLAN (14. Mrz 2016)

Habe jetzt eine eigene Klasse geschrieben, nur habe keine Ahnung wie ich den Konstrukotr übergeben soll.. Bzw was ich in den Getter schreiben soll

```
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;

public class MySQLConnection
{
    public Connection con;
    
    public void Connection()
    {
        try
        {
            Class.forName("com.mysql.jdbc.Driver");
            con = DriverManager.getConnection("jdbc:mysql://MySQLServer/db","benutzer","pw");
        }
        catch (SQLException ex)
        {
            ex.printStackTrace();
        }
        catch (ClassNotFoundException ex)
        {
            Logger.getLogger(MySQLConnection.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public MySQLConnection()
    {
        Connection();
    }
}
```


----------



## Joose (14. Mrz 2016)

powerLAN hat gesagt.:


> .... nur habe keine Ahnung wie ich den Konstrukotr übergeben soll .. Bzw was ich in den Getter schreiben soll


Was bedeutet "Konstruktor übergeben"? Was willst du erreichen?
In welchen getter würdest du gerne was schreiben?

Du könntest nun deine Klasse um eine Methode "execute(String statement)" erweitern. Diese Methode führt dann das übergebene Statement aus.

Hinweis: Methoden beschreiben eine Tätigkeit und sollten auch dem entsprechend benannt werden. (Und beachte dass eig fast alles in Java in lowerCamelCase geschrieben werden, nur Klasse in UpperCamelCase)
Sprich statt "Connection" einfach "connect".


----------



## Jardcore (14. Mrz 2016)

Zuersteinmal Methoden Namen in Java werden im lowerCamelCase geschrieben. In deinem Fall nicht Connection(), sondern connection(). Besser wäre hier aber connect().

In den meisten Fällen sollten Instanzvariablen private und nicht public sein.


powerLAN hat gesagt.:


> Habe jetzt eine eigene Klasse geschrieben, nur habe keine Ahnung wie ich den Konstrukotr übergeben soll.. Bzw was ich in den Getter schreiben soll


Deinen Konstruktor übergibst du nicht, sondern der wird aufgerufen.
zum Beispiel mit

```
MySQLConnection connection = new MySQLConnection();
```

"Getter" könntest du dann so gestalten das mit ihnen möglicherweise Querys ausgeführt werden. Das wären dann aber keine richtigen Getter sondern eher Methoden die dir helfen Daten aus der Datenbank zu bekommen. z.B: query(String statement).

Edit: Joose war wohl schneller


----------



## powerLAN (14. Mrz 2016)

Also, ich habe ja die Methode 'connect', die eine Verbindung mit der Datenbank aufbaut. Und diese Verbindung möchte ich mit einem Konstruktoraufruf in jDialogen im gleichen Package aufrufen, sodass sie diese Verbindung nutzen können und auf die Datenbank zugreifen können.


----------



## powerLAN (14. Mrz 2016)

> Deinen Konstruktor übergibst du nicht, sondern der wird aufgerufen.
> zum Beispiel mit
> 
> ```
> ...


Das habe ich gemacht nur bekommt der Konstruktor dann immer 'null'.


----------



## powerLAN (14. Mrz 2016)

Die Klasse in der ich eine Verbindung aufbaue:

```
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;

public class MySQLConnection
{
    public Connection con;
       
    public void connect()
    {
        try
        {
            Class.forName("com.mysql.jdbc.Driver");
            con = DriverManager.getConnection("jdbc:mysql://Server/Datenbank","Benutzer","PW");
        } 
        catch (SQLException ex) 
        {
            ex.printStackTrace();
        } 
        catch (ClassNotFoundException ex)
        {
            Logger.getLogger(MySQLConnection.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
   
    public MySQLConnection()
    {
        connect();
    }
}
```
jDialog mit dem Konstruktoraufruf:

```
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;

public class Login extends javax.swing.JFrame
{
    public ResultSet res;
    public Statement stat;
    Registrieren reg = new Registrieren(this, true);
    Datenbankverwaltung dbv = new Datenbankverwaltung(this, true);
    DatenbankInformationen dbi = new DatenbankInformationen();
    MySQLConnection connect = new MySQLConnection();
   
    public Login()
    {
        initComponents();
    }

    //Überprüft ob der eingebene Benutzername zu dem Benutzername in der Datenbank passt
    public void checkbenutzername()
    {
        try
        {    
            String benutzername = jTextFieldBenutzername.getText().trim();
            String passwort = jPasswordFieldPasswort.getText().trim();
           
            String sql = "SELECT * FROM benutzer WHERE benutzername = '"+benutzername+"' AND passwort = '"+passwort+"'";

            res = stat.executeQuery(sql);
            //korrektur 
            int count = 0;
            while(res.next())
            {
                count = count + 1;
            }
           
            if(count == 1)
            {
                this.setVisible(false);
                dbv.setVisible(true);
            }
            else if(count > 1)
            {
                JOptionPane.showMessageDialog(null,"Der Account ist doppelt vorhanden.");
            }
            else
            {
                JOptionPane.showMessageDialog(null,"Login fehlgeschlagen!");
            }
           
        } 
        catch (SQLException ex)
        {
            Logger.getLogger(Login.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
```

Fehlermeldung:

```
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at datenbankverwaltung_oberflaeche.Login.checkbenutzername(Login.java:56)
    at datenbankverwaltung_oberflaeche.Login.jButtonLoginActionPerformed(Login.java:183)
    at datenbankverwaltung_oberflaeche.Login.access$000(Login.java:16)
    at datenbankverwaltung_oberflaeche.Login$1.actionPerformed(Login.java:104)
    at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018)
    at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2341)
    at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
    at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
    at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
    at java.awt.Component.processMouseEvent(Component.java:6505)
    at javax.swing.JComponent.processMouseEvent(JComponent.java:3320)
    at java.awt.Component.processEvent(Component.java:6270)
    at java.awt.Container.processEvent(Container.java:2229)
    at java.awt.Component.dispatchEventImpl(Component.java:4861)
    at java.awt.Container.dispatchEventImpl(Container.java:2287)
    at java.awt.Component.dispatchEvent(Component.java:4687)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832)
    at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4492)
    at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4422)
    at java.awt.Container.dispatchEventImpl(Container.java:2273)
    at java.awt.Window.dispatchEventImpl(Window.java:2719)
    at java.awt.Component.dispatchEvent(Component.java:4687)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:735)
    at java.awt.EventQueue.access$200(EventQueue.java:103)
    at java.awt.EventQueue$3.run(EventQueue.java:694)
    at java.awt.EventQueue$3.run(EventQueue.java:692)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
    at java.awt.EventQueue$4.run(EventQueue.java:708)
    at java.awt.EventQueue$4.run(EventQueue.java:706)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:705)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
BUILD SUCCESSFUL (total time: 7 seconds)
```


----------



## Jardcore (14. Mrz 2016)

Ich kenne mich mit jdbc nicht so aus, aber müsstest du nicht bei "stat.executeQuery(sql);" stat irgendwo noch initalisieren.
Wenn du die Connection deiner MySqlConnection() haben möchtest brächte deine Klasse wohl doch noch einen Getter getConnection(). Dieser gibt dir dann die Instanzvariable Connection zurück. In deinem Fall "con".


----------



## Joose (14. Mrz 2016)

powerLAN hat gesagt.:


> Das habe ich gemacht nur bekommt der Konstruktor dann immer 'null'.


Was heißt der Konstruktor bekommt "null"? Ein Konstruktor ist eine spezielle und kann Parameter übergeben bekommen.

Im Zusammenhang mit der NullPointerException vom nächsten Post macht dies natürlich mehr Sinn 


```
public ResultSet res;
    public Statement stat;
......
            String sql = "SELECT * FROM benutzer WHERE benutzername = '"+benutzername+"' AND passwort = '"+passwort+"'";

            res = stat.executeQuery(sql);
            //korrektur
```


```
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at datenbankverwaltung_oberflaeche.Login.checkbenutzername(Login.java:56)
```

Wie Jardcore schon angemerkt hat ist die Variable "stat" nicht initialisiert. Daher versuchst du auf "null" zuzugreifen und davon eine Methode aufzurufen.
-> NullPointer
Der StackTrace hat dir auch genau verraten wo die Exception passiert -> Dateiname + Zeile.


----------



## powerLAN (14. Mrz 2016)

Habe meine Klasse jetzt so gebaut:


```
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.logging.Level;
import java.util.logging.Logger;

public class MySQLConnection
{
    public Connection con;
    public Statement stat;  
   
    public void connect()
    {
        try
        {
            Class.forName("com.mysql.jdbc.Driver");
            con = DriverManager.getConnection("jdbc:mysql://Server/Datenbank","Benutzer","PW");
            stat = con.createStatement();  
        } 
        catch (SQLException ex) 
        {
            ex.printStackTrace();
        } 
        catch (ClassNotFoundException ex)
        {
            Logger.getLogger(MySQLConnection.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
   
    public MySQLConnection()
    {
        connect();
    }
   
    public Connection getConnection()
    {
        return this.con;
    }
}
```


----------



## powerLAN (14. Mrz 2016)

Habe es jetzt hinbekommen. Lag daran, dass das Statement nicht initialisiert war..

```
String sql = "SELECT * FROM benutzer WHERE benutzername = '"+benutzername+"' AND passwort = '"+passwort+"'";

            stat = connect.getConnection().createStatement();
          
            res = stat.executeQuery(sql);
```
Das einzige was ich machen musste war: 

```
stat = connect.getConnection().createStatement();
```


----------



## Joose (14. Mrz 2016)

Hinweis: Du baust dir hier dein Statement mit einfacher Stringverkettung zusammen.
Das ist sehr gefährlich und anfällig für SQL Injection. 
Für ein Testprogramm vielleicht nicht zu beachten, sobald du aber etwas davon produktiv verwenden willst solltest du auf PreparedStatements umsteigen!


----------

