package org.theonefx.wcframework.jdbc.datasource; import java.math.BigDecimal; import java.sql.Blob; import java.sql.Clob; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Statement; import java.sql.Types; /** * @Package cn.nzit.conf.common.utils * @ClassName: JdbcUtils * @author 陈曦 * @date 2010-08-19 10:45:11 * @Description: JDBC工具类,该类封装了数据库资源的获取与释放的所有方法 * 同时,该类使用了dbcp数据库连接池技术,在使用中无需关心数据库连接池的维护。 */ public class JdbcUtils { /** * Constant that indicates an unknown (or unspecified) SQL type. * * @see java.sql.Types */ public static final int TYPE_UNKNOWN = Integer.MIN_VALUE; /** * Close the given JDBC Connection and ignore any thrown exception. This is * useful for typical finally blocks in manual JDBC code. * * @param con * the JDBC Connection to close (may be <code>null</code>) */ public static void closeConnection(Connection con) { if (con != null) { try { con.close(); } catch (SQLException ex) { ex.printStackTrace(); // logger.debug("Could not close JDBC Connection", ex); } catch (Throwable ex) { ex.printStackTrace(); // We don't trust the JDBC driver: It might throw // RuntimeException or Error. // logger.debug("Unexpected exception on closing JDBC Connection", // ex); } } } /** * Close the given JDBC Statement and ignore any thrown exception. This is * useful for typical finally blocks in manual JDBC code. * * @param stmt * the JDBC Statement to close (may be <code>null</code>) */ public static void closeStatement(Statement stmt) { if (stmt != null) { try { stmt.close(); } catch (SQLException ex) { // logger.trace("Could not close JDBC Statement", ex); } catch (Throwable ex) { // We don't trust the JDBC driver: It might throw // RuntimeException or Error. // logger.trace("Unexpected exception on closing JDBC Statement", // ex); } } } /** * Close the given JDBC ResultSet and ignore any thrown exception. This is * useful for typical finally blocks in manual JDBC code. * * @param rs * the JDBC ResultSet to close (may be <code>null</code>) */ public static void closeResultSet(ResultSet rs) { if (rs != null) { try { rs.close(); } catch (SQLException ex) { // logger.trace("Could not close JDBC ResultSet", ex); } catch (Throwable ex) { // We don't trust the JDBC driver: It might throw // RuntimeException or Error. // logger.trace("Unexpected exception on closing JDBC ResultSet", // ex); } } } public static Object getResultSetValue(ResultSet rs, int index, Class<?> requiredType) throws SQLException { if (requiredType == null) { return getResultSetValue(rs, index); } Object value = null; boolean wasNullCheck = false; // Explicitly extract typed value, as far as possible. if (String.class.equals(requiredType)) { value = rs.getString(index); } else if (boolean.class.equals(requiredType) || Boolean.class.equals(requiredType)) { value = Boolean.valueOf(rs.getBoolean(index)); wasNullCheck = true; } else if (byte.class.equals(requiredType) || Byte.class.equals(requiredType)) { value = new Byte(rs.getByte(index)); wasNullCheck = true; } else if (short.class.equals(requiredType) || Short.class.equals(requiredType)) { value = new Short(rs.getShort(index)); wasNullCheck = true; } else if (int.class.equals(requiredType) || Integer.class.equals(requiredType)) { value = new Integer(rs.getInt(index)); wasNullCheck = true; } else if (long.class.equals(requiredType) || Long.class.equals(requiredType)) { value = new Long(rs.getLong(index)); wasNullCheck = true; } else if (float.class.equals(requiredType) || Float.class.equals(requiredType)) { value = new Float(rs.getFloat(index)); wasNullCheck = true; } else if (double.class.equals(requiredType) || Double.class.equals(requiredType) || Number.class.equals(requiredType)) { value = new Double(rs.getDouble(index)); wasNullCheck = true; } else if (byte[].class.equals(requiredType)) { value = rs.getBytes(index); } else if (java.sql.Date.class.equals(requiredType)) { value = rs.getDate(index); } else if (java.sql.Time.class.equals(requiredType)) { value = rs.getTime(index); } else if (java.sql.Timestamp.class.equals(requiredType) || java.util.Date.class.equals(requiredType)) { value = rs.getTimestamp(index); } else if (BigDecimal.class.equals(requiredType)) { value = rs.getBigDecimal(index); } else if (Blob.class.equals(requiredType)) { value = rs.getBlob(index); } else if (Clob.class.equals(requiredType)) { value = rs.getClob(index); } else { // Some unknown type desired -> rely on getObject. value = getResultSetValue(rs, index); } // Perform was-null check if demanded (for results that the // JDBC driver returns as primitives). if (wasNullCheck && value != null && rs.wasNull()) { value = null; } return value; } public static Object getResultSetValue(ResultSet rs, int index) throws SQLException { Object obj = rs.getObject(index); String className = null; if (obj != null) { className = obj.getClass().getName(); } if (obj instanceof Blob) { obj = rs.getBytes(index); } else if (obj instanceof Clob) { obj = rs.getString(index); } else if (className != null && ("oracle.sql.TIMESTAMP".equals(className) || "oracle.sql.TIMESTAMPTZ".equals(className))) { obj = rs.getTimestamp(index); } else if (className != null && className.startsWith("oracle.sql.DATE")) { String metaDataClassName = rs.getMetaData().getColumnClassName(index); if ("java.sql.Timestamp".equals(metaDataClassName) || "oracle.sql.TIMESTAMP".equals(metaDataClassName)) { obj = rs.getTimestamp(index); } else { obj = rs.getDate(index); } } else if (obj != null && obj instanceof java.sql.Date) { if ("java.sql.Timestamp".equals(rs.getMetaData().getColumnClassName(index))) { obj = rs.getTimestamp(index); } } return obj; } public static boolean supportsBatchUpdates(Connection con) { try { DatabaseMetaData dbmd = con.getMetaData(); if (dbmd != null) { if (dbmd.supportsBatchUpdates()) { // logger.debug("JDBC driver supports batch updates"); return true; } else { // logger.debug("JDBC driver does not support batch updates"); } } } catch (SQLException ex) { // logger.debug("JDBC driver 'supportsBatchUpdates' method threw exception", // ex); } catch (AbstractMethodError err) { // logger.debug("JDBC driver does not support JDBC 2.0 'supportsBatchUpdates' method", // err); } return false; } public static String commonDatabaseName(String source) { String name = source; if (source != null && source.startsWith("DB2")) { name = "DB2"; } else if ("Sybase SQL Server".equals(source) || "Adaptive Server Enterprise".equals(source) || "sql server".equals(source)) { name = "Sybase"; } return name; } public static boolean isNumeric(int sqlType) { return Types.BIT == sqlType || Types.BIGINT == sqlType || Types.DECIMAL == sqlType || Types.DOUBLE == sqlType || Types.FLOAT == sqlType || Types.INTEGER == sqlType || Types.NUMERIC == sqlType || Types.REAL == sqlType || Types.SMALLINT == sqlType || Types.TINYINT == sqlType; } public static String lookupColumnName(ResultSetMetaData resultSetMetaData, int columnIndex) throws SQLException { String name = resultSetMetaData.getColumnLabel(columnIndex); if (name == null || name.length() < 1) { name = resultSetMetaData.getColumnName(columnIndex); } return name; } /** * Convert a column name with underscores to the corresponding property name * using "camel case". A name like "customer_number" would match a * "customerNumber" property name. * * @param name * the column name to be converted * @return the name using "camel case" */ public static String convertUnderscoreNameToPropertyName(String name) { StringBuffer result = new StringBuffer(); boolean nextIsUpper = false; if (name != null && name.length() > 0) { if (name.length() > 1 && name.substring(1, 2).equals("_")) { result.append(name.substring(0, 1).toUpperCase()); } else { result.append(name.substring(0, 1).toLowerCase()); } for (int i = 1; i < name.length(); i++) { String s = name.substring(i, i + 1); if (s.equals("_")) { nextIsUpper = true; } else { if (nextIsUpper) { result.append(s.toUpperCase()); nextIsUpper = false; } else { result.append(s.toLowerCase()); } } } } return result.toString(); } }