📄 dbconnectionmanager.java
字号:
/** * $RCSfile$ * $Revision: 4263 $ * $Date: 2006-07-05 14:44:36 -0700 (Wed, 05 Jul 2006) $ * * Copyright (C) 2004 Jive Software. All rights reserved. * * This software is published under the terms of the GNU Public License (GPL), * a copy of which is included in this distribution. */package org.jivesoftware.database;import org.jivesoftware.util.ClassUtils;import org.jivesoftware.util.JiveGlobals;import org.jivesoftware.util.Log;import java.io.*;import java.sql.*;/** * Central manager of database connections. All methods are static so that they * can be easily accessed throughout the classes in the database package.<p> * * This class also provides a set of utility methods that abstract out * operations that may not work on all databases such as setting the max number * or rows that a query should return. * * @author Jive Software * @see ConnectionProvider */public class DbConnectionManager { private static ConnectionProvider connectionProvider; private static final Object providerLock = new Object(); // True if connection profiling is turned on. Always false by default. private static boolean profilingEnabled = false; // True if the database support transactions. private static boolean transactionsSupported; // True if the database requires large text fields to be streamed. private static boolean streamTextRequired; // True if the database supports the Statement.setMaxRows() method. private static boolean maxRowsSupported; // True if the database supports the Statement.setFetchSize() method. private static boolean fetchSizeSupported; // True if the database supports correlated subqueries. private static boolean subqueriesSupported; // True if the database supports scroll-insensitive results. private static boolean scrollResultsSupported; // True if the database supports batch updates. private static boolean batchUpdatesSupported; private static DatabaseType databaseType = DatabaseType.unknown; private static SchemaManager schemaManager = new SchemaManager(); /** * Returns a database connection from the currently active connection * provider. (auto commit is set to true). */ public static Connection getConnection() throws SQLException { if (connectionProvider == null) { synchronized (providerLock) { if (connectionProvider == null) { // Attempt to load the connection provider classname as // a Jive property. String className = JiveGlobals.getXMLProperty("connectionProvider.className"); if (className != null) { // Attempt to load the class. try { Class conClass = ClassUtils.forName(className); setConnectionProvider((ConnectionProvider)conClass.newInstance()); } catch (Exception e) { Log.error("Warning: failed to create the " + "connection provider specified by connection" + "Provider.className. Using the default pool.", e); setConnectionProvider(new DefaultConnectionProvider()); } } else { setConnectionProvider(new DefaultConnectionProvider()); } } } } Connection con = connectionProvider.getConnection(); if (con == null) { Log.error("WARNING: ConnectionManager.getConnection() " + "failed to obtain a connection."); } // See if profiling is enabled. If yes, wrap the connection with a // profiled connection. if (profilingEnabled) { return new ProfiledConnection(con); } else { return con; } } /** * Returns a Connection from the currently active connection provider that * is ready to participate in transactions (auto commit is set to false). */ public static Connection getTransactionConnection() throws SQLException { Connection con = getConnection(); if (isTransactionsSupported()) { con.setAutoCommit(false); } return con; } /** * Closes a PreparedStatement and Connection. However, it first rolls back the transaction or * commits it depending on the value of <code>abortTransaction</code>. */ public static void closeTransactionConnection(PreparedStatement pstmt, Connection con, boolean abortTransaction) { try { if (pstmt != null) { pstmt.close(); } } catch (Exception e) { Log.error(e); } closeTransactionConnection(con, abortTransaction); } /** * Closes a Connection. However, it first rolls back the transaction or * commits it depending on the value of <code>abortTransaction</code>. */ public static void closeTransactionConnection(Connection con, boolean abortTransaction) { // test to see if the connection passed in is null if (con == null) { return; } // Rollback or commit the transaction if (isTransactionsSupported()) { try { if (abortTransaction) { con.rollback(); } else { con.commit(); } } catch (Exception e) { Log.error(e); } } try { // Reset the connection to auto-commit mode. if (isTransactionsSupported()) { con.setAutoCommit(true); } } catch (Exception e) { Log.error(e); } try { // Close the db connection. con.close(); } catch (Exception e) { Log.error(e); } } /** * Closes a result set. This method should be called within the finally section of * your database logic, as in the following example: * * <pre> * public void doSomething(Connection con) { * ResultSet rs = null; * PreparedStatement pstmt = null; * try { * pstmt = con.prepareStatement("select * from blah"); * rs = pstmt.executeQuery(); * .... * } * catch (SQLException sqle) { * Log.error(sqle); * } * finally { * ConnectionManager.closeResultSet(rs); * ConnectionManager.closePreparedStatement(pstmt); * } * } </pre> */ public static void closeResultSet(ResultSet rs) { try { if (rs != null) { rs.close(); } } catch (SQLException e) { Log.error(e); } } /** * Closes a statement. This method should be called within the finally section of * your database logic, as in the following example: * * <pre> * public void doSomething(Connection con) { * PreparedStatement pstmt = null; * try { * pstmt = con.prepareStatement("select * from blah"); * .... * } * catch (SQLException sqle) { * Log.error(sqle); * } * finally { * ConnectionManager.closePreparedStatement(pstmt); * } * } </pre> * * @param stmt the statement. */ public static void closeStatement(Statement stmt) { try { if (stmt != null) { stmt.close(); } } catch (Exception e) { Log.error(e); } } /** * Closes a result set, statement and database connection (returning the connection to * the connection pool). This method should be called within the finally section of * your database logic, as in the following example: * * <pre> * Connection con = null; * PrepatedStatment pstmt = null; * ResultSet rs = null; * try { * con = ConnectionManager.getConnection(); * pstmt = con.prepareStatement("select * from blah"); * rs = psmt.executeQuery(); * .... * } * catch (SQLException sqle) { * Log.error(sqle); * } * finally { * ConnectionManager.closeConnection(rs, pstmt, con); * }</pre> * * @param stmt the statement. * @param con the connection. */ public static void closeConnection(ResultSet rs, Statement stmt, Connection con) { closeResultSet(rs); closeStatement(stmt); closeConnection(con); } /** * Closes a statement and database connection (returning the connection to * the connection pool). This method should be called within the finally section of * your database logic, as in the following example: * <p/> * <pre> * Connection con = null; * PrepatedStatment pstmt = null; * try { * con = ConnectionManager.getConnection(); * pstmt = con.prepareStatement("select * from blah"); * .... * } * catch (SQLException sqle) { * Log.error(sqle); * } * finally { * DbConnectionManager.closeConnection(pstmt, con); * }</pre> * * @param stmt the statement. * @param con the connection. */ public static void closeConnection(Statement stmt, Connection con) { try { if (stmt != null) { stmt.close(); } } catch (Exception e) { Log.error(e); } closeConnection(con); } /** * Closes a database connection (returning the connection to the connection pool). Any * statements associated with the connection should be closed before calling this method. * This method should be called within the finally section of your database logic, as * in the following example: * <p/> * <pre> * Connection con = null; * try { * con = ConnectionManager.getConnection(); * .... * } * catch (SQLException sqle) { * Log.error(sqle); * } * finally { * DbConnectionManager.closeConnection(con); * }</pre> * * @param con the connection. */ public static void closeConnection(Connection con) { try { if (con != null) { con.close(); } } catch (Exception e) { Log.error(e); } } /** * Creates a scroll insensitive Statement if the JDBC driver supports it, or a normal * Statement otherwise. * * @param con the database connection. * @return a Statement * @throws SQLException if an error occurs. */ public static Statement createScrollableStatement(Connection con) throws SQLException { if (isScrollResultsSupported()) { return con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); } else { return con.createStatement(); } } /** * Creates a scroll insensitive PreparedStatement if the JDBC driver supports it, or a normal * PreparedStatement otherwise. * * @param con the database connection. * @param sql the SQL to create the PreparedStatement with. * @return a PreparedStatement * @throws java.sql.SQLException if an error occurs. */ public static PreparedStatement createScrollablePreparedStatement(Connection con, String sql) throws SQLException { if (isScrollResultsSupported()) { return con.prepareStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); } else { return con.prepareStatement(sql); } } /** * Scrolls forward in a result set the specified number of rows. If the JDBC driver * supports the feature, the cursor will be moved directly. Otherwise, we scroll * through results one by one manually by calling <tt>rs.next()</tt>. * * @param rs the ResultSet object to scroll. * @param rowNumber the row number to scroll forward to. * @throws SQLException if an error occurs. */ public static void scrollResultSet(ResultSet rs, int rowNumber) throws SQLException { // If the driver supports scrollable result sets, use that feature. if (isScrollResultsSupported()) { if (rowNumber > 0) { rs.setFetchDirection(ResultSet.FETCH_FORWARD); // We will attempt to do a relative fetch. This may fail in SQL Server if // <resultset-navigation-strategy> is set to absolute. It would need to be // set to looping to work correctly. // If so, manually scroll to the correct row. try { rs.relative(rowNumber); } catch (SQLException e) { for (int i = 0; i < rowNumber; i++) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -