# JDBC - Verständnisfrage



## Devox (17. Aug 2014)

Hallo zusammen,

ich habe gestern Nacht einen interessanten Beitrag zum Thema 'JDBC - Connection close' gelesen. 
How to Close JDBC Resources Properly – Every Time | Shine Technologies

Wer keine Lust hat den Link anzuklicken, hier das Code-Beispiel aus dem Artikel um das es mir geht:


```
Connection connection = dataSource.getConnection();
try {
Statement statement = connection.createStatement();

try {
ResultSet resultSet = statement.executeQuery("some query");

try {
// Do stuff with the result set.
} finally {
resultSet.close();
}
} finally {
statement.close();
}
} finally {
connection.close();
}
```

Dazu hätte ich nun 2 Fragen. 

1)
In der gezeigten Klasse wird nur eine SQL-Abfrage/Anweisung ausgeführt. Bisher habe ich immer eine "DatabaseHandler"-Klasse erstellt, welche eine Verbindung aufbaut und alle SQL-Abfragen meines Programms enthält und diese bei Bedarf aufruft. Dadurch habe ich natürlich das Problem mit dem verbindung.close(). 
Unter dem Gesichtspunkt - CODE-OPTIMIERUNG:
Erstellt man für jede SQL-Abfrage eine eigene Java-Klasse z.B. nach dem oben gezeigten Pattern? Oder wie macht ihr Profis das? 

2)
Wie bindet man den Treiber in diesem Beispiel korrekt ein? Dieser wird in dem Beispiel ja glaube ich mit dataSource.getConnection() eingebunden (oder irre ich mich??). Erstelle ich einfach eine Klasse "dataSource" mit der Methode "getConnection" und dieser steht dann sowas drin? 


```
public getConnection(){
		try {
			Class.forName("com.mysql.jdbc.Driver");
			con = DriverManager.getConnection ("jdbc:mysql://localhost:3306/bla", "root", "");
			System.out.println("Datenbank Verbindung hergestellt!");
		} catch (ClassNotFoundException | SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
	}
```

Habe mit sowas noch nicht viel Erfahrung, würde mir aber gerne versuchen direkt einen guten Programmier-Stil anzueignen.

Ich hoffe mir kann da jemand ein paar Tipps geben und Ihr versteht worum es mir geht 

lg


----------



## stg (17. Aug 2014)

Der Verbindungsaufbau selbst ist immer relativ langsam. Daher hält man oft physisch einige Verbindungen zur Datenbank in einem ConntectionPool offen und das logische öffnen und schließen von Verbindungen geschieht, indem man Verbindungen aus dem Pool bezieht und wieder zurückgibt. Alle gängigen JDBC-Treiber sollten de Möglichkeit des Connection-Pooling von Haus aus unterstützen, so dass man sich selbst nicht mehr um viel kümmern muss. Resultat ist jedenfalls, dass du innerhalb deines Codes immer wieder Verbindungen beziehen und danach direkt wieder schließen kannst, ohne das physisch die Verbindung zur Datenbank wirklich geschlossen wird. 

Für jedes SQL-Statement eine eigene Klasse zu entwerfen ist meist Quatsch, ebenso, wie alles einfach in eine Klasse zu packen. So pauschal kann man das nicht beantworten. 
In der Regel aber sollte die Klasse, die sich um die Verwaltung der Datenbankverbindungen kümmert, getrennt von den tatsächlichen Abfragen gehalten werden, denn dann kannst du diese (etwa wenn du auf eine andere Datenbank umziehst oder von gewöhnlichen auf gepoolte Verbindungen wechseln willst) relativ problemlos austauschen.
Wo und wie du die SQL-Statements bündelst, hängt ein wenig vom Anwendungsfall ab. Sinnvoll kann beispielsweise eine Aufteilung nach verwendeten Entity sein, also etwa eine Controller-Klasse je Tabelle in der Datenbank. Oder etwa eine Klasse pro View, in der du auf die jeweiligen UI angepasste Abfragen sammelst. Wie gesagt, pauschal kann man das nicht komplett beantworten. Redundanzen sollten jedoch natürlich möglichst vermieden werden.


----------



## taro (17. Aug 2014)

Ich möchte mich kurz mit einer Frage dazu anschließen:

Da ja alle 3 Objekte das Interface AutoClosable implementieren, sollte nicht ein try-with-resources reichen, um den gleichen Effekt zu erzielen?


```
try (Connection connection = dataSource.getConnection();
                Statement statement = connection.createStatement();
                ResultSet resultSet = statement.executeQuery("some query");
                ) {
// Do stuff with the result set.
        }
```


----------

