wake-up-neo.com

JDBC-Verbindungspooling mit C3P0

Folgendes ist meine Hilfsklasse, um eine DB-Verbindung zu erhalten:

Ich habe das C3P0-Verbindungspooling wie in here beschrieben verwendet.

public class DBConnection {

    private static DataSource dataSource;
    private static final String DRIVER_NAME;
    private static final String URL;
    private static final String UNAME;
    private static final String PWD;

    static {

        final ResourceBundle config = ResourceBundle
                .getBundle("props.database");
        DRIVER_NAME = config.getString("driverName");
        URL = config.getString("url");
        UNAME = config.getString("uname");
        PWD = config.getString("pwd");

        dataSource = setupDataSource();
    }

    public static Connection getOracleConnection() throws SQLException {
        return dataSource.getConnection();
    }

    private static DataSource setupDataSource() {
        ComboPooledDataSource cpds = new ComboPooledDataSource();
        try {
            cpds.setDriverClass(DRIVER_NAME);
        } catch (PropertyVetoException e) {
            e.printStackTrace();
        }
        cpds.setJdbcUrl(URL);
        cpds.setUser(UNAME);
        cpds.setPassword(PWD);
        cpds.setMinPoolSize(5);
        cpds.setAcquireIncrement(5);
        cpds.setMaxPoolSize(20);
        return cpds;
    }
}

in der DAO schreibe ich so etwas:

try {
            conn = DBConnection.getOracleConnection();

            ....


} finally {
    try {
        if (rs != null) {
            rs.close();
        }
        if (ps != null) {
            ps.close();
        }
        if (conn != null) {
            conn.close();
        }
    } catch (SQLException e) {
        logger
                .logError("Exception occured while closing cursors!", e);

    }

Jetzt frage ich mich, ob ich noch etwas anderes bereinigen möchte, als die im finally-Block aufgeführten Cursors (connection/statement/resultSet/preparStatement) zu schließen.

Was ist diese Bereinigung ?? Wann und wo soll ich das machen?

Sollten Sie im obigen Code etwas falsch finden, weisen Sie bitte darauf hin.

28
jai

Bei einer gepoolten Datenquelle werden die Verbindungen im Pool nicht wirklich geschlossen. Sie werden lediglich in den Pool zurückgegeben. Wenn die Anwendung jedoch heruntergefahren wird, sollten diese Verbindungen zur Datenbank ordnungsgemäß und tatsächlich geschlossen werden, wo die endgültige Bereinigung erfolgt.

Das c3p0-Projekt ist übrigens ziemlich tot im Wasser. Ich empfehle, stattdessen Apache Commons DBCP zu verwenden, es wird immer noch gewartet.

23
skaffman

DAOs sollten nicht dafür verantwortlich sein, eine Verbindung zur Datenbank herzustellen. Sie haben keine Möglichkeit zu wissen, wann sie als Teil einer größeren Transaktion verwendet werden. Sie sollten die Datenquelle oder die Verbindungsinstanz an DAO übergeben.

Wenn einer der zu schließenden Aufrufe in Ihrem endgültigen Block eine Ausnahme auslöst, wird keiner der folgenden Aufrufe aufgerufen. Jeder muss in einem eigenen try/catch-Block sein. Ich habe sie als statische Methoden in eine Utility-Klasse gestellt.

6
duffymo

Der Code sieht gut aus für mich, aber ich würde eine Hilfsmethode schreiben, die die Schließoperationen durchführt, oder Sie erhalten diesen ausführlichen Endblock in jedem DAO oder jeder Methode. Vielleicht sollten Sie drei separate try-catch-Blöcke um die close-Vorgänge schreiben, um sicherzustellen, dass die Verbindung geschlossen ist, unabhängig davon, ob die Anweisung und das Resultset eine Exection ausgelöst haben. Beachten Sie auch, dass der Javadoc sagt

Wenn ein Statement-Objekt geschlossen wird, wird auch das aktuelle ResultSet-Objekt (sofern vorhanden) geschlossen. 

Sie müssen also das Resultset im obigen Beispiel nicht schließen, aber Sie könnten es tun.

Die verknüpfte Bereinigungsmethode dient zum Schließen der Datenquelle, was in den meisten Projekten nicht erforderlich ist, da DS so lange läuft, wie Ihre App ausgeführt wird.

5
Tim Büthe

Ich benutze Play Framework und Scala. Das folgende Beispiel befindet sich im Play-Projekt.

Schritt 1. Aufbau

Wenn Sie in build.sbt mysql/hive als Datenbank verwenden, müssen Sie diese Eigenschaften hinzufügen. 

libraryDependencies ++ = Seq (
   jdbc,
  "mysql" % "mysql-connector-Java" % "5.1.31",
  "org.Apache.Hive" % "Hive-jdbc" % "0.12.0",
  "com.mchange" % "c3p0" % "0.9.2.1"
)

Schritt 2. wie kann man darauf zugreifen? Sie müssen die c3p0-Bibliothek importieren.

import com.mchange.v2.c3p0.ComboPooledDataSource

Schritt 3. und dann müssen Sie eine Instanz erstellen.

val cpds = new ComboPooledDataSource()
cpds.setDriverClass(...)
cpds.setJdbcUrl(...)
cpds.setUser(...)
cpds.setPassword(...)

Schritt 4. Du bekommst eine Verbindung

cpds.getConnection
0
Haimei