# Wo "Connection" Object erstellen?



## KartoffelKiffer (23. Jan 2008)

Hallo,

meine Frage ist eigentlich kurz und präzise.

Und zwar bahnt sich ein neues Projekt an. In diesem werde ich mittels JDBC auf eine MySQL Datenbank zugreifen. Jetzt frage ich mich allerdings, wie oft, und wo ich einen Connect zur Datenbank machen muss. Jedesmal, wenn ich ein neues Statement absetze? Oder starte ich in meiner "Start"klasse ein neues Connection-Object, stelle den Connect also her, und greife aus allen anderen Klasse, wo ich diese Connection ebenfalls benötige, darauf zu?



Mfg Tom


----------



## DocRandom (23. Jan 2008)

Hi KartoffelKiffer! (lol was für ein nick)


Dein Stichwort lautet #ConnectionPool!

lg
DocRandom


----------



## L-ectron-X (23. Jan 2008)

Die Verbindung zu einer Datenbank herzustellen ist etwas "teuer". Daher ist es üblich zu Beginn eine Verbindung herzustellen und diese bis zum Beenden des Programms zu verwenden.


----------



## KartoffelKiffer (24. Jan 2008)

Hallo,

ich danke Euch Zweien wirklich sehr.

Gerade heute morgen hatte ich nämlich schon wieder nach einigen Tests "Too many connections" in der Datenbank stehen. Dämlich wie ich bin habe ich nämlich eine Klasse gehabt, die immer wieder einen neuen Connect aufmachte, und dieses Object dann zurück gegeben hat. Teilweise habe ich einen Connect nicht mal mehr nach der Verwendung geschlossen.

Jetzt handhabe ich es so, dass ich ein Statement erstelle (mittels con.createStatement()) und danach direkt den Connect mittels con.close() schließe. Es gibt Ausnahmen wo der Connect noch benötigt wird. Die Regel ist aber, dass der Connect geschlossen werden kann.

Ich war mir nicht sicher ob das so funktioniert, darum habe ich einen Test gemacht:
1.) Erstellung des Connection-Objekts "Connection con = de.xxx.database.Connect.getConnection();"
2.) Erstellung eines Statement-Objekts "Statement stmnt = con.createStatement()";
3.) Schließen der Connection "con.close();"
4.) Erstellen eines ResultSet-Objekts "ResultSet rs = stmnt.executeQuery(...)"

So funktionierte es einwandfrei. Gibt es Einwände den Connect direkt nach Erstellung des Statement-Objekts zu schließen? Wie gesagt, 100% sicher bin ich mir nicht, aber der Test war erfolgreich.

Jetzt sieht meine Connect-Klasse wiefolgt aus:

```
Klasse de.xxx.database.Connect
-----------------------------
private static javax.sql.PooledConnection pc;
	
// Einmaliger Aufruf direkt zu Anfang meines Programms
	public static void connect() {
		
		pc = null;
		try {
			
			ReadConfig config = new ReadConfig("config"); // config-Datei die die Daten für den MySQL-Connect beinhaltet
			
			MysqlConnectionPoolDataSource ds = new MysqlConnectionPoolDataSource();
			ds.setUrl(config.getProperty("database_connectionstring"));
			ds.setUser(config.getProperty("database_user"));
			ds.setPassword(config.getProperty("database_pass"));
			
			pc = ds.getPooledConnection();
		} catch (Exception e) {
			
			System.out.println(e.toString());
		}
	}
	
	public static Connection getConnection() {
		
		try {
		
			return pc.getConnection();
		} catch (Exception e) {
			
			System.out.println(e.toString());
			return null;
		}
	}
```

Ist dies so ok, oder habe ich noch einen Fehler begannen/etwas nicht berücksichtigt?




Mfg Tom


----------



## Niki (24. Jan 2008)

Wie schon oben erwähnt solltest du *EINE* Connection am Anfang der Applikation erstellen. Wenn die Applikation beendet wird solltest du die Connection wieder schließen. Dafür einfach einen WindowListener an das Hauptfenster hängen und wenn windowClosing aufgerufen wird die Connection schließen. Bau dir einfach ein Objekt welches die Connection statisch hält. Etwa so:

```
private static Connection connection = null;

public static Connection getConnection(){
  if(connection == null){
    connection = DriverManager.getConnection("...");
  }

  return connection;
}

public static void closeConnection(){
  if(connection != null)
    connection.close();
}
```

Wenn du einen Server hättest auf den sich mehrere Clients verbinden könntest du einen Pool aufbauen. Für jede Transaktion würde dann eine Connection aus dem Pool geholt werden und beim Beenden der Transaktion wieder in den Pool zurück gelegt werden.


----------



## maki (24. Jan 2008)

> Wie schon oben erwähnt solltest du EINE Connection am Anfang der Applikation erstellen.


Dann bräuchte doch gar keinen ConnectionPool..

Was er vergessen hat, ist die Connection aus dem Pool wieder zu schliessen.


----------



## KartoffelKiffer (24. Jan 2008)

Bitte korrigiere mich, aber genau das habe ich doch gemacht.

// Edit: War auf Niki bezogen


----------



## Niki (24. Jan 2008)

Ja, du verwendest halt einen Pool. Das ist bei einer SingleUser-Anwendung nicht notwendig, kannst du aber auch machen. Wenn du einen Pool verwendest solltest du die Connection halt jedes mal zurück legen (bei DataSource macht das das close automatisch).


----------

