jdbc操作大观园

最近公司使用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/>
	 * 
	 * &lt?xml version='1.0' encoding='utf-8'?&gt<br/> &ltContext&gt<br/>
	 * &lt!-- Default set of monitored resources --&gt<br/>
	 * &ltWatchedResource&gtWEB-INF/web.xml&lt/WatchedResource&gt<br/>
	 * &ltResource driverClass="com.mysql.jdbc.Driver"<br/>
	 * jdbcUrl="jdbc:mysql://localhost:3306/hw_man_13?characterEncoding=GBK&amp;autoReconnect=true&amp;failOverReadOnly=false&amp;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/> /&gt<br/>
	 * &lt/Context&gt<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

你可能感兴趣的:(java,sql,jdbc,mybatis)