JDBC Datenbankzugriff

bazookajoe

Grünschnabel
Hi!
Ich hoffe das is hier das richtige Forum, konnte mein Anliegen nicht klar einordnen :P

Folgendes:
Ich will eine Klasse schreiben, die auf eine Datenbank zugreift und verschiedene SELECT Abfragen, Ausgabe von Tabellen als HTML, Ausgabe der gesamten Datenbank usw. ermöglicht!
Ich habe mir die Methoden createConnection() und closeConnection() geschrieben und verwende diese je am Anfang und am Ende der einzelnen Methoden. Dies bedeutet ich kann z.b. keine Methode public ResultSet query(String query) schreiben, weil zu dem Zeitpunkt, wo das ResultSet von einer anderen Methode weiterverarbeitet werden soll, die Connection und das Statement bereits geclosed sind...

Nun meine Frage: Ist es überhaupt sinnvoll in jeder Methode an den Anfang createConnection() und ans Ende closeConnection() zu schreiben ?
Ich dachte mir es ist evtl nicht gut wenn eine Connection sehr lange offen ist und erst per Hand irgendwann später geschlossen wird. Andererseits kommen so natürlich sehr viele connects und disconnects zusammen was evtl auch nicht gut ist ?

Gibt es da konkrete Vorstellungen oder Ansätze wie man es machen sollte ?

Möglich wäre ja z.B. die Abfrage als CachedRowSet zu realisieren, dann könnte ich in jeder Methode gleich die Connection und alle Resourcen schließen... allerdings wären dann halt viele connects und disconnects da..

Wenn ich die Connection offen lasse, könnte ich direkt mit dem ResultSet arbeiten, was allerdings vllt nicht ganz sicher ist !?

Wäre schön ein paar Ansätze zu hören, wie man es vorzugsweise machen sollte :P
cya
 
Hi!
Folgendes:
Ich will eine Klasse schreiben, die auf eine Datenbank zugreift und verschiedene SELECT Abfragen, Ausgabe von Tabellen als HTML, Ausgabe der gesamten Datenbank usw. ermöglicht!
Ich habe mir die Methoden createConnection() und closeConnection() geschrieben und verwende diese je am Anfang und am Ende der einzelnen Methoden. Dies bedeutet ich kann z.b. keine Methode public ResultSet query(String query) schreiben, weil zu dem Zeitpunkt, wo das ResultSet von einer anderen Methode weiterverarbeitet werden soll, die Connection und das Statement bereits geclosed sind...

Ich hätte es wie folgt gemacht. Wenn du nur eine Verbindung benötigst, dann kannst du das ganze über ein Singleton lösen. Diese Methode ist static und gibt immer die gleiche Instanz der Klasse zurück.

Die main-Methode die beim Start aufgerufen wird:

Java:
package tutorials.de;

import java.sql.SQLException;

public class Main {
	
	public static void main(String[] args) {
		DBConnection db = DBConnection.getInstance();
		try {
			//Öffnen (soll beim Starten des Programms aufgerufen werden
			db.createConnection();

			//Query senden (kannst du dann überall im Programm machen)
			db.executeQuery("SELECT name FROM User;");
			
			//schließen (sollst dann beim Beenden des Programms geschlossen werden
			db.closeConnection();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

}

Die DBConnection mit Singleton:

Java:
package tutorials.de;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class DBConnection {
	private static DBConnection instance;
	private Connection con;
	private Statement stmt;
	
	protected DBConnection(){
		try {
			Class.forName("TREIBERNAME");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
	
	public static DBConnection getInstance(){
		if(instance == null){
			instance = new DBConnection();
		}
		return instance;
	}
	
	public void createConnection() throws SQLException{
		//Verbindung wird geöffnet
		con = DriverManager.getConnection("..pfad..", "user", "passwort");
	}
	
	public ResultSet executeQuery(String sqlCommand) throws SQLException{
		return stmt.executeQuery(sqlCommand);
	}
	
	public void closeConnection() throws SQLException{
		//Verbindung wird geschlossen
		con.close();
	}
}

Ich behandle hier nur Querys. Also DELETE, UPDATE, INSERT INTO müssen anders behandelt werden ;)

Greeze Chimaira
 
Sorry, wenn ich hier wiedermal dazwischen grätsche, aber der Code is ziemlich unterirdisch. Er tut sicher das, was er tun soll, ist aber weder robust noch gut. Es gibt weder sauberes Exceptionhandling noch irgendeine Form von Resourcenbereiningung. Was passiert denn, wenn dir beim Abschicken eine Exception fliegt? DIe Connection bleibt dann offen. stmt wird nie initialisiert, folglich fliegt da auf jeden fall eine NPE. con.close ohne Test auf NULL zu rufen ist auch foo. Mal abgesehen davon, das Standardsingletons der Tod für jede Form von Testbarkeit sind und somit den Client nie ohne Datenbank testen können wirst. Unitttesting bleibt damit aussen vor :(

Ich kann nur zum 100000. mal auf folgende Punkte hinweisen:

1. DataSource benutzen. Von DriverManager wird schon im JavaDoc abgeraten. z.B. kann man sich das Commons DBCP Jar in den Classpath legen und new BasicDataSource() machen - fertig.

2. Gibt es div. Bibliotheken, die einem solchen Lowlevel Code abnehmen, die wesentlich robuster und vorallem X Millionenfach im Einsatz sind und somit bullet proof.

Hier gibt es ein Tutorial zum JdbcTemplate von Spring und wie es zu benutzen ist. Mit dessen Hilfe kann man prima DAOs auf JDBC Basis bauen, die wirklich sauber gecoded sind.

Gruß
Ollie
 
Hi,

also das mit dem Statement habe ich vergessen, jo. Gebe ich zu. Gut ich weiß, dass der Code nicht wirklich gut ist, aber bin ja noch beim lernen.

Ich habe es mit dem DriverManager gelernt und erst gar nicht versucht es anders zu machen.

Das hier habe ich nur auf die schnelle gemacht. Exception-Handling gar nicht erst beachtet.

Mit Spring habe ich noch nie gearbeitet.

Was würdest du denn in diesem Fall für ein Buch (oder irgendeine andere Lektüre) empfehlen?

Greeze Chimaira
 
Zuletzt bearbeitet:
Hehe, deswegen bin ich ja auch so vorsichtig eingestiegen. Will niemanden harsch anfahren oder so. Ich hab nur wahrscheinlich schon zu viele Applikationen gesehen, in denen DB Zugriffe unnötig ungünstig implementiert wurden. Ausserdem sind wir ja hier um uns gegenseitig zu helfen. Ich hoffe also, dass meine Kritik als konstruktiv angesehen wurde, und nicht besserwisserisch. Ich wollte in diesem Fall nur die sauberere Alternative anführen, bevor jemand hier Copy & Paste versucht und damit die nächste Applikation fehlerhaft aufsetzt ;).

Konntest du jetzt mit den Tipps was anfangen? Bzw. ist noch etwas unverständlich? Bitte: keine Angst vor Spring. Spring ist kein "Hier hast du 10 MB Jars - mach!" Framework. Man muss auch keine große XML Konfiguration anlegen und sich da reinarbeiten für den Anfang. Für das Tutorial reicht wirklich das spring-jdbc.jar und los gehts.

Also keine Angst vor großen Namen! ;)

REINHAUN!
 
Zurück