PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Java: geschlossene Connection wieder öffnen


Zarathustra
2004-10-02, 18:50:21
Ich erstelle eine Connection via DriverManager, benutze sie und schliesse sie dann wieder mit conn.close(). Aber wenn ich auf conn wieder eine neue erstellen und die benutzen will, gibts ne SQLException, weil, so der Wortlaut connection.close aufgerufen wurde.
Wie krieg ich die Connection wieder auf?

HellHorse
2004-10-02, 19:14:20
Also du versuchst per DriverManager eine neue Connection zu erstellen und der will nicht? Du hast auch ein neues Statement erstell, oder kommtst du gar nicht erst so weit?

Anosten: Code her :wink:

Zarathustra
2004-10-02, 21:47:19
Ja, mir ist auch grad eingefallen, dass natürlich erst ein neues Statement erstellt werden muss, aber wo mache ich das?
Mein Programm hat 2 Teile mit je eigenem GUI: 1. den Connector und 2. das Tool selbst. In ersterem erstelle ich die Verbindung und trenne sie auch, und im zweiten erstelle ich das Statement aus der übergebenen Connection und arbeite damit. Dort finden die SQL-Aufrufe in inneren Klassen, nämlich den Listenern (für JList und JButton) statt.

Vielleicht kann ich, indem ich das Statement schon im Connector gleich mit der Connection erstelle und mit dem ToolGUI-Konstruktor und "this.stmt=stmt" übergebe, eine Referenz für das Tool erzeugen? (So wie ich das auch mit conn mache.)

EDIT:
Hmm dann konmmt das:
"local variable stmt is accessed from within inner class; needs to be declared final
ResultSet rs = stmt.executeQuery(sqlCommand);"

Die 'inner class' ist
"gui.tableList.addListSelectionListener(new
ListSelectionListener()
{
public void valueChanged(ListSelectionEvent e)
{..."

Aber final setzen kann ich das Statement nicht einfach. Was nun? :(

EDIT2:
Ich habs nun über eine Methode der ToolGUI gemacht, über die die innere Klasse das Statement erhält, aber trotzdem kann ich die erst einmal geschlossene Verbindung nicht wieder öffnen!
Mir scheint, als würde "conn.close()" irgendeine Sperre vor die SQL-Ausführung setzen, vielleicht kann (muss) man die zurücksetzen?

HellHorse
2004-10-03, 14:26:26
Mir scheint, als würde "conn.close()" irgendeine Sperre vor die SQL-Ausführung setzen, vielleicht kann (muss) man die zurücksetzen?
Das kann kaum sein und widerspricht meiner ganzen Erfahrung mit MySQL und JDBC.

Folgendes läuft bei mir problemlos, egal ob ich eine neue DataSource verwende, oder die alte nehme.

import javax.sql.DataSource;

import junit.framework.TestCase;

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

public class MySQLTest extends TestCase {
private static final String TEST_STRING = "some String";

private DataSource dataSource = getDataSource();

public void setUp() {
Connection conn = null;
Statement stmt = null;
try {
//conn = getNewConnection();
conn = dataSource.getConnection();
stmt = conn.createStatement();
stmt.executeUpdate("INSERT INTO sample_table (field_1) values ('"+TEST_STRING+"')");
} catch (SQLException e) {
fail("set up failed");
} finally {
closeBoth(conn, stmt);
}
}

public void testReconnect() throws SQLException {
Connection conn = null;
Statement stmt = null;
try {
//conn = getNewConnection();
conn = dataSource.getConnection();
stmt = conn.createStatement();
ResultSet result = stmt.executeQuery("SELECT field_1 FROM sample_table");
assertTrue(result.next());
assertEquals(TEST_STRING, result.getString(1));
assertFalse(result.next());
stmt.executeUpdate("DELETE FROM sample_table");
} finally {
closeBoth(conn, stmt);
}
}

private static void closeBoth(Connection conn, Statement stmt) {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
//nothing
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
//nothing
}
}
}

private static Connection getNewConnection() throws SQLException {
return getDataSource().getConnection();
}

private static DataSource getDataSource() {
return getMySQLDataSource("127.0.0.1", 3306, "test", "root", "");
}

public static DataSource getMySQLDataSource(String host, int port, String db,String user, String password) {
MysqlDataSource source = new MysqlDataSource();
source.setServerName(host);
source.setPortNumber(port);
source.setDatabaseName(db);
source.setUser(user);
source.setPassword(password);
return source;
}
}


Damit das läuft muss du in der Datenbank test die Tabelle sample_table miti den Attribut field_1 von etwas String ähnlichem erstellen.
Und natürlich musst du auch Username, Passwort, Port, Server und DB anpassen. Und sicher nicht einen leeren String als root Passwort nehmen ;)

Zarathustra
2004-10-03, 17:01:38
Dann muss es daran liegen, dass Connection und Statement erstellt, übergeben und in einer anderen Klasse verwendet werden, welche sich dann beschwert.
Sie müssten also quasi "neu übergeben" werden...
...was eigentlich mit dem Konstruktor geschieht.
Da müssen Methoden her...
Wie kann ich von ToolGUI auf die ConnectorGUI-Klasse zugreifen, die mit dem ToolGUI-Konstruktor die beiden Sachen übergeben hat? Gibts eine Funktion, die die 'aufrufende Klasse' zurückgibt?

HellHorse
2004-10-03, 19:53:55
Dann muss es daran liegen, dass Connection und Statement erstellt, übergeben und in einer anderen Klasse verwendet werden, welche sich dann beschwert.
Sie müssten also quasi "neu übergeben" werden...
...was eigentlich mit dem Konstruktor geschieht.
Da müssen Methoden her...
:confused:
Wie kann ich von ToolGUI auf die ConnectorGUI-Klasse zugreifen, die mit dem ToolGUI-Konstruktor die beiden Sachen übergeben hat?
Tönt irgendwie als wärs im Moment ein recht grosser Murks. Ich würde mal ein Redesign in Betracht ziehen und all das DB Zeugs in einen kleinen DB-Layer tun. Im simpelsten Fall ist das bloss eine Klasse. Dort kannst du dich dann mit Connections, Statements und Queries rumgschlagen. Von aussen siehst du bloss eine Applikationsobjekte die reingehen und rauskommen.
Gibts eine Funktion, die die 'aufrufende Klasse' zurückgibt?
Nee, sonst noch Wünsche?

Zarathustra
2004-10-03, 20:24:34
Nee, sonst noch Wünsche?
Hätt ja sein können, Java ist voller zeugs das ich noch nicht kenne :rolleyes:

Ok, dann werd ich das auslagern, danke erstmal für deine Hilfe. :redface:

EDIT:
OK, hab ne extra-Klasse gemacht, läuft nun alles bestens. Eine Erfahrung die mach erst gemacht haben muss, das wird nicht nochmal vorkommen. =)