jdbc操作大观园
程序员文章站
2022-07-13 17:02:12
...
最近公司使用jdbc和mybatis比较多,于是自己试着写了一个方便的类库打包,便于自己使用。高手指教。
package org.liufei.jweb.sql.util; import java.sql.Connection; import java.sql.SQLException; import org.apache.log4j.Logger; /** * JDBC事物工具。 * * @author 刘飞 * */ public abstract class JdbcTransaction<T> { private Logger logger = Logger.getLogger(JdbcTransaction.class); private Connection conn; private boolean isCloseConnection = false; /** * 自动控制的事物块。 * * @param conn * 数据库连接 * @param isCloseConnection * 完成事物以后是否关闭连接, 默认为false不关闭。 */ public JdbcTransaction(Connection conn, boolean isCloseConnection) { super(); this.conn = conn; this.isCloseConnection = isCloseConnection; } public final T doInTransaction() throws SQLException { T result = null; boolean autoCommit = false; if (this.conn != null) { try { /** * 保存Connection原始属性 */ autoCommit = this.conn.getAutoCommit(); /** * 在本代码快里设置Connection非自动提交 */ if (this.conn.getAutoCommit()) { this.conn.setAutoCommit(false); } /** * 执行事务代码块 */ result = this.doInTransaction(this.conn); /** * 提交事务 */ this.conn.commit(); /** * 恢复Connection的原始属性, 以免对其他代码造成影响。 */ this.conn.setAutoCommit(autoCommit); } catch (SQLException e) { logger.error("事物代码块异常 ", e); try { this.conn.rollback(); } catch (SQLException e1) { logger.error("事物回滚时异常 ", e); throw new SQLException("事物回滚时异常 : " + e1.getLocalizedMessage()); } throw new SQLException("事物代码块异常 : " + e.getLocalizedMessage()); } finally { try { this.conn.setAutoCommit(autoCommit); } catch (SQLException e) { logger.error("恢复Connection自动提交属性异常 ", e); throw new SQLException("恢复Connection自动提交属性异常 : \n" + e.getLocalizedMessage()); } if (this.isCloseConnection) { try { this.conn.close(); this.conn = null; } catch (SQLException e) { logger.error("数据库连接关闭时 ", e); throw new SQLException("数据库连接关闭时 : " + e.getLocalizedMessage()); } } } } return result; } protected abstract T doInTransaction(Connection conn) throws SQLException; }
package org.liufei.jweb.sql.util; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import org.liufei.jweb.sql.callback.Callback; import org.liufei.jweb.sql.callback.ConnectionCallback; import org.liufei.jweb.sql.callback.ResultSetCallback; import org.liufei.jweb.sql.callback.SqlCallback; /** * * @author 刘飞 * */ public class JdbcUser { public static <T> T executeConnectionQueryCallback(final Connection conn, final String sql, ResultSetCallback<T> callback) throws SQLException { return new SqlCallback<T, ResultSet>(){ public T doInSQLCallback(String sql, Callback<T, ResultSet> callback) throws SQLException { return callback.doInSql(JdbcUtil.executeQuery(conn, sql)); }} .doInSQLCallback(sql, callback) ; } public static <T> T executeSQLDML(final Connection conn, boolean isCloseConnection, final ConnectionCallback<T> callback) throws SQLException { return new JdbcTransaction<T>(conn, isCloseConnection){ @Override public T doInTransaction(Connection conn) throws SQLException { return callback.doInSql(conn); }} .doInTransaction(); } }
package org.liufei.jweb.sql.util; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Savepoint; import java.sql.Statement; import java.util.Properties; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.sql.DataSource; import org.apache.log4j.Logger; import org.liufei.jweb.sql.callback.ConnectionCallback; /** * jdbc操作工具。 * * @author 刘飞 * */ public class JdbcUtil { private static final Logger logger = Logger.getLogger(JdbcUtil.class); /** * 用于执行对数据库的查询。 * * @param conn * @param sql * @return * @throws SQLException */ public static ResultSet executeQuery(Connection conn, String sql) throws SQLException { if (conn != null && sql != null) { if(isSupportsResultSet_TYPE_SCROLL_INSENSITIVE_CONCUR_READ_ONLY(conn) && isSupportsResultSetType_TYPE_SCROLL_INSENSITIVE(conn)) { return conn.prepareStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY).executeQuery(); } else { return conn.prepareStatement(sql).executeQuery(); } } else { logger.error("数据库连接对象和SQL参数不能为空 : java.sql.Connection[conn : null], java.lang.String[sql : null].") ; throw new SQLException( "数据库连接对象和SQL参数不能为空 : java.sql.Connection[conn : null], java.lang.String[sql : null]."); } } /** * * @param <T> * @param conn * @param callback * @param isCloseConnection * 完成事物以后是否关闭连接。 * @return * @throws SQLException */ public static <T> T executeSQL(final Connection conn, final ConnectionCallback<T> callback, boolean isCloseConnection) throws SQLException { return (T) new JdbcTransaction<T>(conn, isCloseConnection){ @Override public T doInTransaction(Connection conn) throws SQLException { return callback.doInSql(conn); }} .doInTransaction(); } /** * 用于执行对数据库的修改更新和删除。 * * @param conn * @param sql * @param isCloseConnection * 完成事物以后是否关闭连接。 * @return * @throws SQLException */ public static int executeSQLDML(Connection conn, final String sql, boolean isCloseConnection) throws SQLException { if (conn != null && sql != null) { JdbcTransaction<Integer> jdbcTransaction = new JdbcTransaction<Integer>( conn, isCloseConnection) { @Override public Integer doInTransaction(Connection conn) throws SQLException { int result = 0 ; if(isSupportsResultSet_TYPE_SCROLL_INSENSITIVE_CONCUR_UPDATABLE(conn) && isSupportsResultSetType_TYPE_SCROLL_INSENSITIVE(conn)) { /** * 执行数据库更新 */ result = conn.prepareStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE).executeUpdate(); } else { /** * 执行数据库更新 */ result = conn.prepareStatement(sql).executeUpdate(); } return result; } }; return jdbcTransaction.doInTransaction(); } else { logger.error("数据库连接对象和SQL参数不能为空 : java.sql.Connection[conn : null], java.lang.String[sql : null].") ; throw new SQLException( "数据库连接对象和SQL参数不能为空 : java.sql.Connection[conn : null], java.lang.String[sql : null]."); } } /** * PreparedStatement 执行批处理。 * * @param conn * @param batchSql * 批量更新SQL * @param parameters * 二维参数列表, 用于注入SQL中 * @param times * 每多少条执行一次更新 * @param isCloseConnection * 完成事物以后是否关闭连接。 * @return 返回此批处理共影响的数据条数。 * @throws SQLException */ public static int executePreparedStatementSQLBatch(Connection conn, final String batchSql, final Object[][] parameters, final int times, final boolean isCloseConnection) throws SQLException { if (conn != null && batchSql != null) { if (batchSql.length() > 0) { if(isSupportsBatchUpdates(conn)) { JdbcTransaction<Integer> jdbcTransaction = new JdbcTransaction<Integer>( conn, isCloseConnection) { @Override public Integer doInTransaction(Connection conn) throws SQLException { int result = 0; /** * 执行批量操作 */ PreparedStatement pstmt = conn .prepareStatement(batchSql); int i = 1; for (Object[] params : parameters) { int j = 1; for (Object param : params) { pstmt.setObject(j, param); j++; } if (i % times == 0) { int[] rs = pstmt.executeBatch(); for (int k : rs) { result += k; } } i++; } release(null, pstmt, null, false) ; return result; } }; return jdbcTransaction.doInTransaction(); } else { throw new RuntimeException("this database does not supports batch updates.") ; } } else { return 0; } } else { logger.error("数据库连接对象和SQL参数不能为空 : java.sql.Connection[conn : null], java.lang.String[sql : null].") ; throw new SQLException( "数据库连接对象和SQL参数不能为空 : java.sql.Connection[conn : null], java.lang.String[sql : null]."); } } /** * Statement执行批处理。 * * @param conn * @param batchSql * @param isCloseConnection * 完成事物以后是否关闭连接。 * @return 返回此批处理共影响的数据条数。 * @throws SQLException */ public static int executeStatementSQLBatch(Connection conn, final String[] batchSql, final int times, final boolean isCloseConnection) throws SQLException { if (conn != null && batchSql != null) { if (batchSql.length > 0) { if(isSupportsBatchUpdates(conn)) { JdbcTransaction<Integer> jdbcTransaction = new JdbcTransaction<Integer>( conn, isCloseConnection) { @Override public Integer doInTransaction(Connection conn) throws SQLException { int rs = 0; /** * 执行批量操作 */ Statement stmt = conn.createStatement(); int k = 0 ; for (String sql : batchSql) { if (sql.trim().length() > 0) { stmt.addBatch(sql); } if(k % times == 0) { int[] result = stmt.executeBatch(); for (int i : result) { rs += i; } } } release(null, stmt, null, false) ; return rs; } }; return jdbcTransaction.doInTransaction(); } else { throw new RuntimeException("this database does not supports batch updates.") ; } } else { return 0; } } else { logger.error("数据库连接对象和SQL参数不能为空 : java.sql.Connection[conn : null], java.lang.String[sql : null].") ; throw new SQLException( "数据库连接对象和SQL参数不能为空 : java.sql.Connection[conn : null], java.lang.String[sql : null]."); } } /** * 释放数据库资源。 * * @param rs * @param stmt * @param conn * @param isCloseConnection * 是否关闭数据库连接。 * @throws SQLException */ public static void release(ResultSet rs, Statement stmt, Connection conn, boolean isCloseConnection) throws SQLException { if (rs != null) { rs.close(); rs = null; } if (stmt != null) { stmt.close(); stmt = null; } if (conn != null) { if (!conn.isClosed() && !conn.getAutoCommit()) { conn.rollback(); } if (isCloseConnection) { conn.close(); conn = null; } } } /** * * @param connection * @param autoCommit * @throws SQLException */ public static void setAutoCommit(Connection connection, boolean autoCommit) throws SQLException { connection.setAutoCommit(autoCommit); } /** * 是否支持ResultSet.TYPE_SCROLL_INSENSITIVE * @param connection * @return * @throws SQLException */ public static boolean isSupportsResultSetType_TYPE_SCROLL_INSENSITIVE(Connection connection) throws SQLException { return connection.getMetaData().supportsResultSetType(ResultSet.TYPE_SCROLL_INSENSITIVE) ; } /** * 是否支持ResultSet.CONCUR_READ_ONLY * @param connection * @return * @throws SQLException */ public static boolean isSupportsResultSet_TYPE_SCROLL_INSENSITIVE_CONCUR_READ_ONLY(Connection connection) throws SQLException { return connection.getMetaData().supportsResultSetConcurrency(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY) ; } /** * 是否支持ResultSet.CONCUR_UPDATABLE * @param connection * @return * @throws SQLException */ public static boolean isSupportsResultSet_TYPE_SCROLL_INSENSITIVE_CONCUR_UPDATABLE(Connection connection) throws SQLException { return connection.getMetaData().supportsResultSetConcurrency(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE) ; } /** * 是否支持 ANSI92 SQL * @param connection * @return * @throws SQLException */ public static boolean isSupportsANSI92FullSQL(Connection connection) throws SQLException { return connection.getMetaData().supportsANSI92FullSQL() ; } /** * 是否支持SelectForUpdate * @param connection * @return * @throws SQLException */ public static boolean isSupportsSelectForUpdate(Connection connection) throws SQLException { return connection.getMetaData().supportsSelectForUpdate() ; } /** * 是否支持批量更新。 * @param connection * @return * @throws SQLException */ public static boolean isSupportsBatchUpdates(Connection connection) throws SQLException { return connection.getMetaData().supportsBatchUpdates() ; } /** * 是否支持事务保存点 * @param connection * @return * @throws SQLException */ public static boolean isSupportsSavepoints(Connection connection) throws SQLException { return connection.getMetaData().supportsSavepoints() ; } /** * 设置事务保存点 * @param connection * @param name * @return * @throws SQLException */ public static Savepoint setSavePoint(Connection connection, String name) throws SQLException { if (isSupportsSavepoints(connection)) { return connection.setSavepoint(name); } else { throw new RuntimeException("this database does not supports savepoints.") ; } } /** * 回滚到事务点 * @param connection * @param savepoint * @throws SQLException */ public static void rollback(Connection connection, Savepoint savepoint) throws SQLException { if (savepoint == null) { connection.rollback(); } else { if(isSupportsSavepoints(connection)) connection.rollback(savepoint); else connection.rollback(); } } /** * 回滚到事务点 * @param connection * @throws SQLException */ public static void rollback(Connection connection) throws SQLException { connection.rollback(); } /** * 提交事务 * @param connection * @param savepoint */ public static void commit(Connection connection, Savepoint savepoint) throws SQLException { if(savepoint == null) { if (!connection.getAutoCommit()) { connection.commit(); } } else { if(isSupportsSavepoints(connection)) { if (!connection.getAutoCommit()) { connection.releaseSavepoint(savepoint); } } else { if (!connection.getAutoCommit()) { connection.commit(); } } } } /** * 提交事务 * @param connection */ public static void commit(Connection connection) throws SQLException { if (!connection.getAutoCommit()) { connection.commit(); } } /** * Classpath下加载属性文件资源。 * * @param filePath * 文件路径(Classpath路径) * @return * @throws IOException */ public static Properties loadPropsClassLoader(String filePath) throws IOException { Properties props = new Properties(); InputStream in = JdbcUtil.class.getClassLoader().getResourceAsStream( filePath); props.load(in); in.close(); return props; } /** * Classpath下加载属性文件资源。 * * @param filePath * 文件路径(文件系统路径) * @return * @throws IOException */ public static Properties loadPropsSystem(String filePath) throws IOException { Properties props = new Properties(); InputStream in = new FileInputStream(new File(filePath)); props.load(in); in.close(); return props; } /** * 获取数据库连接数据源。 * * @param jndiName * jndi名称 * @return * @throws NamingException */ public static DataSource getDataSource(String jndiName) throws NamingException { Context ctx = new InitialContext(); DataSource ds = (DataSource) ctx.lookup(jndiName); return ds; } /** * 测试数据库连接是否有效。 * * @param driver * @param user * @param password * @param url * @return */ public static boolean testConnection(String driver, String user, String password, String url) { try { Class.forName(driver).newInstance(); Connection connection = DriverManager.getConnection(url, user, password); DatabaseMetaData metaData = connection.getMetaData(); if (user.equals(metaData.getUserName())) { return true; } } catch (InstantiationException e) { logger.error("测试数据库连接异常", e) ; } catch (IllegalAccessException e) { logger.error("测试数据库连接异常", e) ; } catch (ClassNotFoundException e) { logger.error("测试数据库连接异常", e) ; } catch (SQLException e) { logger.error("测试数据库连接异常", e) ; } return false; } }
/** * jdbc */ package org.liufei.sql; /** * get a database datasource({@link org.liufei.sql.DataSourceConnection}) * connection({@link java.sql.Connection}) from jdbc * * @author liufei * */ public interface JdbcDataSource extends DataSourceConnection { /** * 返回数据库驱动字符串。 * * @return */ String getDriver(); /** * 返回连接数据库的URL * * @return */ String getURL(); /** * 返回数据库的用户名 * * @return */ String getUsername(); /** * 返回与已绑定用户名对应数据库密码 * * @return */ String getPassword(); }
/** * jndi */ package org.liufei.sql; import javax.naming.NamingException; import javax.sql.DataSource; /** * get a database datasource({@link org.liufei.sql.DataSourceConnection}) * connection({@link java.sql.Connection}) from jndi * * @author liufei * */ public interface JndiDataSource extends DataSourceConnection { /** * 返回一个可用的的jndi名称。 如:java:comp/env/jdbc/mysql <br/> * * <?xml version='1.0' encoding='utf-8'?><br/> <Context><br/> * <!-- Default set of monitored resources --><br/> * <WatchedResource>WEB-INF/web.xml</WatchedResource><br/> * <Resource driverClass="com.mysql.jdbc.Driver"<br/> * jdbcUrl="jdbc:mysql://localhost:3306/hw_man_13?characterEncoding=GBK&autoReconnect=true&failOverReadOnly=false&zeroDateTimeBehavior=convertToNull"<br/> * user="root"<br/> password="root"<br/> name="jdbc/mysql"<br/> * factory="org.apache.naming.factory.BeanFactory"<br/> * type="com.mchange.v2.c3p0.ComboPooledDataSource"<br/> * initialPoolSize="2"<br/> maxPoolSize="2"<br/> maxIdleTime="25000"<br/> * idleConnectionTestPeriod ="18000"<br/> auth="Container"<br/> * acquireIncrement="3"<br/> checkoutTimeout="200000"<br/> /><br/> * </Context><br/> * * @return */ String getJndiName(); /** * 获取已绑定jndi名称(通过getJndiName()方法绑定)的数据源 * * @return * @throws NamingException */ DataSource getDataSource() throws NamingException; /** * 获取制定jndi名称的数据源 * * @param jndiname * @return * @throws NamingException */ DataSource getDataSource(String jndiname) throws NamingException; }
package org.liufei.sql; import java.sql.Connection; import java.sql.SQLException; /** * get a database datasource({@link org.liufei.sql.DataSourceConnection}) connection({@link java.sql.Connection}) * * @author liufei * */ public interface DataSourceConnection { /** * 返回一个活跃的可用连接 * * @link java.sql.Connection * @return 返回一个活跃的可用连接 * @throws SQLException */ Connection getConnection() throws SQLException; /** * 返回一个活跃的可用连接 * @link java.sql.Connection * @param username 需要进一步验证用户名 * @param password 需要进一步验证密码 * @return 返回一个活跃的可用连接 * @throws SQLException */ Connection getConnection(String username, String password) throws SQLException; }
package org.liufei.sql.impl; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.util.logging.Level; import java.util.logging.Logger; import org.liufei.sql.JdbcDataSource; import org.liufei.sql.util.ClasspathConfig; /** * 默认的jdbc实现。 * * @author 刘飞 * */ public class Jdbc implements JdbcDataSource { private static final Logger logger = Logger.getLogger(Jdbc.class.getName()); @Override public String getDriver() { return ClasspathConfig.getDriver(); } @Override public String getPassword() { return ClasspathConfig.getPassword(); } @Override public String getURL() { return ClasspathConfig.getUrl(); } @Override public String getUsername() { return ClasspathConfig.getUsername(); } @Override public Connection getConnection() throws SQLException { try { return this.getConnection(this.getDriver(), this.getURL(), this .getUsername(), this.getPassword()); } catch (InstantiationException e) { logger .log(Level.WARNING, "加载数据库驱动时异常:\n" + e.getLocalizedMessage()); return null; } catch (IllegalAccessException e) { logger .log(Level.WARNING, "加载数据库驱动时异常:\n" + e.getLocalizedMessage()); return null; } catch (ClassNotFoundException e) { logger .log(Level.WARNING, "加载数据库驱动时异常:\n" + e.getLocalizedMessage()); return null; } } @Override public Connection getConnection(String username, String password) throws SQLException { if (!(username.equals(getUsername()) && password.equals(getPassword()))) { logger.log(Level.WARNING, "非法的用户名和密码.\n"); return null; } else { try { return this.getConnection(this.getDriver(), this.getURL(), this .getUsername(), this.getPassword()); } catch (InstantiationException e) { logger.log(Level.WARNING, "加载数据库驱动时异常:\n" + e.getLocalizedMessage()); return null; } catch (IllegalAccessException e) { logger.log(Level.WARNING, "加载数据库驱动时异常:\n" + e.getLocalizedMessage()); return null; } catch (ClassNotFoundException e) { logger.log(Level.WARNING, "加载数据库驱动时异常:\n" + e.getLocalizedMessage()); return null; } } } /** * * @param driver * @param url * @param username * @param password * @return * @throws SQLException * @throws InstantiationException * @throws IllegalAccessException * @throws ClassNotFoundException */ private Connection getConnection(String driver, String url, String username, String password) throws SQLException, InstantiationException, IllegalAccessException, ClassNotFoundException { Class.forName(driver).newInstance(); return DriverManager.getConnection(url, username, password); } }
package org.liufei.sql.impl; import java.sql.Connection; import java.sql.SQLException; import java.util.logging.Level; import java.util.logging.Logger; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.sql.DataSource; import org.liufei.sql.JndiDataSource; import org.liufei.sql.util.ClasspathConfig; /** * 默认的jndi实现。 * @author 刘飞 * */ public class Jndi implements JndiDataSource { private static final Logger logger = Logger.getLogger(Jndi.class.getName()); @Override public DataSource getDataSource() throws NamingException { return this.getDataSource(this.getJndiName()); } @Override public DataSource getDataSource(String jndiname) throws NamingException { Context ctx = new InitialContext(); DataSource ds = (DataSource)ctx.lookup(jndiname); return ds; } @Override public String getJndiName() { return ClasspathConfig.getJndiname(); } @Override public Connection getConnection() throws SQLException { try { return this.getDataSource().getConnection(); } catch (NamingException e) { logger.log(Level.WARNING, "JNDI名称查找失败 : " + e.getLocalizedMessage()) ; return null ; } } @Override public Connection getConnection(String username, String password) throws SQLException { try { return this.getDataSource().getConnection(username, password); } catch (NamingException e) { logger.log(Level.WARNING, "JNDI名称查找失败 : " + e.getLocalizedMessage()) ; return null ; } } }
package org.liufei.sql.callback; import java.sql.SQLException; import java.sql.Wrapper; /** * 在SQL api包中的所有接口中回调。 * * @author 刘飞 * * @param <T> * 返回类型 * @param <K> * sql api */ public interface Callback<T, K extends Wrapper> { /** * 在SQL api包中的所有接口中回调。 * * @param k * SQL api包中的所有接口 * @return * @throws SQLException */ T doInSql(K k) throws SQLException; } package org.liufei.sql.callback;
import java.sql.SQLException;
import java.sql.Wrapper;
/**
*
* @author 刘飞
*
* @param <T>
* 返回类型。
* @param <K>
* sql api的回调。
*/
public interface SqlCallback<T, K extends Wrapper> {
/**
* 调用一个回调对象,完成真正的回调转换。
*
* @param sql
* @param callback
* @return
* @throws SQLException
*/
T doInSQLCallback(String sql, Callback<T, K> callback) throws SQLException;
}
package org.liufei.sql.callback; import java.sql.Connection; /** * 在Connection中回调。 * @author 刘飞 * * @param <T> */ public interface ConnectionCallback<T> extends Callback<T, Connection>{ }
package org.liufei.sql.callback; import javax.sql.DataSource; /** * DataSource中回调。 * * @author 刘飞 * * @param <T> */ public interface DataSourceCallback<T> extends Callback<T, DataSource> { }
package org.liufei.sql.callback; import java.sql.PreparedStatement; /** * 在PreparedStatement中回调。 * @author 刘飞 * * @param <T> */ public interface PreparedStatementCallback<T> extends Callback<T, PreparedStatement>{ }
package org.liufei.sql.callback; import java.sql.ResultSet; /** * 在ResultSet中回调。 * @author 刘飞 * * @param <T> */ public interface ResultSetCallback<T> extends Callback<T, ResultSet> { }
package org.liufei.sql.callback; import java.sql.Statement; /** * 在Statement回调。 * @author 刘飞 * * @param <T> */ public interface StatementCallback<T> extends Callback<T, Statement> { }
package org.liufei.sql.callback.help; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.ParameterMetaData; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Statement; import java.sql.Wrapper; import javax.sql.DataSource; import org.liufei.sql.callback.CallableStatementCallback; import org.liufei.sql.callback.Callback; import org.liufei.sql.callback.ConnectionCallback; import org.liufei.sql.callback.DataSourceCallback; import org.liufei.sql.callback.DatabaseMetaDataCallback; import org.liufei.sql.callback.ParameterMetaDataCallback; import org.liufei.sql.callback.PreparedStatementCallback; import org.liufei.sql.callback.ResultSetCallback; import org.liufei.sql.callback.ResultSetMetaDataCallback; import org.liufei.sql.callback.SqlCallback; import org.liufei.sql.callback.StatementCallback; /** * SQL回调的抽象实现。 * * @author 刘飞 * * @param <T> * 返回类型 * @param <K> * sql api的回调。 */ public abstract class CommonSqlCallback<T> implements SqlCallback<T, Wrapper> { protected Connection connection = null ; protected DataSource dataSource = null ; private static final int DEFAULT_TIMEOUT = 2 ;//2秒中的数据库连接测试。 public CommonSqlCallback(Connection connection) throws SQLException { super(); this.connection = connection; if( this.connection.isClosed() || this.connection.isValid(DEFAULT_TIMEOUT) ) { throw new SQLException( this.getClass() + " construct sql connection exception : Illegal unavailable database connection ." ) ; } } public CommonSqlCallback(DataSource dataSource) throws SQLException { this(dataSource.getConnection()) ; this.dataSource = dataSource; } @Override public T doInSQLCallback(String sql, Callback<T, Wrapper> callback) throws SQLException { if(this.connection != null) { if(callback instanceof ConnectionCallback) { return callback.doInSql(this.connection) ; } else if(callback instanceof PreparedStatementCallback) { PreparedStatement pstmt = this.connection.prepareStatement(sql) ; return callback.doInSql(pstmt) ; } else if(callback instanceof StatementCallback) { Statement stmt = this.connection.createStatement() ; return callback.doInSql(stmt) ; } else if(callback instanceof CallableStatementCallback) { CallableStatement cstmt = this.connection.prepareCall(sql) ; return callback.doInSql(cstmt) ; } else if(callback instanceof DatabaseMetaDataCallback) { DatabaseMetaData dbmd = this.connection.getMetaData() ; return callback.doInSql(dbmd) ; } else if(callback instanceof ResultSetCallback) { ResultSet rs = this.connection.prepareCall(sql).executeQuery() ; return callback.doInSql(rs) ; } else if(callback instanceof ResultSetMetaDataCallback) { ResultSetMetaData rsmd = this.connection.prepareStatement(sql).getMetaData() ; return callback.doInSql(rsmd) ; } else if(callback instanceof ParameterMetaDataCallback) { ParameterMetaData pmd = this.connection.prepareCall(sql).getParameterMetaData() ; return callback.doInSql(pmd) ; } else { // no result } } if(this.dataSource != null) { if(callback instanceof DataSourceCallback) { return callback.doInSql(this.dataSource) ; } } return null ; } }
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/test?characterEncoding=GBK&autoReconnect=true&failOverReadOnly=false&zeroDateTimeBehavior=convertToNull jdbc.username=root jdbc.password=root jdbc.jndiname=java:comp/env/jdbc/mysql
上一篇: NIO初步了解
下一篇: Java网络服务器编程(NIO版)