All Downloads are FREE. Search and download functionalities are using the official Maven repository.

me.icymint.libra.jdbc.JdbcSupport Maven / Gradle / Ivy

package me.icymint.libra.jdbc;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;

import javax.sql.DataSource;

import me.icymint.libra.jdbc.dialect.Dialect;
import me.icymint.libra.jdbc.dialect.Dialects;
import me.icymint.libra.jdbc.param.DefaultParameter;
import me.icymint.libra.jdbc.param.Parameter;
import me.icymint.libra.jdbc.query.Execute;
import me.icymint.libra.jdbc.query.Executes;
import me.icymint.libra.jdbc.query.Query;
import me.icymint.libra.jdbc.query.SqlQuery;
import me.icymint.libra.jdbc.query.multi.QueryToken;
import me.icymint.libra.jdbc.query.multi.QueryTokens;
import me.icymint.libra.jdbc.result.ArrayResultMap;
import me.icymint.libra.jdbc.result.ListResult;
import me.icymint.libra.jdbc.result.Result;
import me.icymint.libra.jdbc.result.ResultMap;
import me.icymint.libra.jdbc.result.ScalarResult;
import me.icymint.libra.jdbc.result.ScalarResultMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * JDBC模板支持类,其提供基础的JDBC执行模板,并执行对数据库数据源的检测。
 * 
 * @author Daniel Yu
 * @since 2013-3-14
 * 
 */
public abstract class JdbcSupport {

	/**
	 * 数据源识别,并获取数据源基础信息。
	 * 
	 * @author Daniel Yu
	 * @since 2013-3-14
	 * 
	 */
	private class DataSourceTest implements SqlQuery {

		@Override
		public Dialect query(Connection conn, String sql, Void p)
				throws JdbcAccessException {
			try {
				username = conn.getMetaData().getUserName();
				url = conn.getMetaData().getURL();
				driver = conn.getMetaData().getDriverName();
				return Dialects.fetch(conn.getMetaData()
						.getDatabaseProductName());
			} catch (SQLException e) {
				throw new JdbcAccessException(e);
			}
		}

	}

	private final static ArrayResultMap RESULTMAP_ARRAY = new ArrayResultMap();

	private final static ScalarResultMap RESULTMAP_SCALAR = new ScalarResultMap();

	/**
	 * 批量执行SQL语句,其语句通过分号分割执行。仅针对无参数无返回值的批量SQL语句。
	 */
	public final static Executes QUERY_EXECUTES = new Executes();

	/**
	 * 查询结果为单个Object数组。
	 */
	public final static Result RESULT_SCALAR_ARRAY = RESULT_SCALAR(RESULTMAP_ARRAY);

	/**
	 * 查询结果为Object数组List。
	 */
	public final static Result> RESULT_LIST_ARRAY = RESULT_LIST(RESULTMAP_ARRAY);

	/**
	 * 查询结果为单个Object。
	 */
	public final static Result RESULT_SCALAR = RESULT_SCALAR(RESULTMAP_SCALAR);

	/**
	 * 查询结果为Object的List。
	 */
	public final static Result> RESULT_LIST = RESULT_LIST(RESULTMAP_SCALAR);

	/**
	 * 默认参数赋值对象。其能够保证null值被正确赋值。
	 * 
	 * @param types
	 */
	public final static 

DefaultParameter PARAMETER_DEFAULT(int[] types) { return new DefaultParameter(types); } /** * 批量执行更新,例如INSERT语句和UPDATE语句。 * * @param ps */ public final static

Execute

QUERY_EXECUTE(Collection

ps) { return new Execute

(ps); } /** * 执行查询。 * * @param r * @param p */ public final static Query QUERY_QUERY(Result r, P p) { return new Query(r, p); } private final static ListResult RESULT_LIST(ResultMap rm) { return new ListResult(rm); } private final static ScalarResult RESULT_SCALAR(ResultMap rm) { return new ScalarResult(rm); } /** * 日志。 */ protected Logger logger = LoggerFactory.getLogger(getClass()); /** * 数据源。 */ private final DataSource ds; /** * 数据库方言,其通过数据源来自动识别。 */ private final Dialect dialect; /** * 数据库用户名。 */ private String username = null; /** * 数据库驱动类名称。 */ private String driver = null; /** * 数据库访问路径。 */ private String url = null; protected JdbcSupport(DataSource ds) { this.ds = ds; this.dialect = this.queryOnce(new DataSourceTest(), null, null); logger.debug("识别数据源为" + dialect.getDatabaseProductName()); initDao(ds, dialect); } /** * 批量无参数执行方法,其为轻量级方法,支持多条SQL语句的合并执行。 * * @param sql * @throws JdbcAccessException */ public void execute(String sql) throws JdbcAccessException { this.queryOnce(QUERY_EXECUTES, sql, null); } /** * 批量执行母方法,其为重量级方法,需要自定义参数输入方式。 * * @param sql * @param ps * @param p * @throws JdbcAccessException */ public

void execute(String sql, Parameter

ps, Collection

p) throws JdbcAccessException { this.queryOnce(QUERY_EXECUTE(p), sql, ps); } /** * 获取Jdbc连接 * * @throws JdbcAccessException */ protected Connection getConnection() throws JdbcAccessException { try { return ds.getConnection(); } catch (SQLException e) { throw new JdbcAccessException(e); } } /** * 获取方言。 */ public Dialect getDialect() { return dialect; } /** * 获取数据库驱动类名称。 */ public String getDriver() { return driver; } /** * 获取数据库连接路径。 */ public String getUrl() { return url; } /** * 获取数据库登录用户名。 */ public String getUsername() { return username; } /** * 初始化。 * * @param ds * @param dialect */ protected abstract void initDao(DataSource ds, Dialect dialect); /** * 事务型执行核心方法。其用于一次性提交一批sql代码。 * * @param x * @param ys * @param z * @param p */ protected T multiQueries(QueryToken x, QueryToken[] ys, QueryToken z, P p) { return this.queryOnce(new QueryTokens(x, ys, z), null, p); } /** * 所有查询的母方法。其为重量级方法,需要定义参数输入以及结果输出的具体执行过程。 * * @param sql * @param p * @param r * @param param * @throws JdbcAccessException */ public T query(String sql, Parameter

p, Result r, P param) throws JdbcAccessException { return this.queryOnce(QUERY_QUERY(r, param), sql, p); } /** * 单次执行SQL核心模板方法。 * * @param sq * @param sql * @param p * @throws JdbcAccessException */ private T queryOnce(SqlQuery sq, String sql, P p) throws JdbcAccessException { Connection conn = getConnection(); try { conn.setAutoCommit(false); if (sql != null) logger.debug("执行语句:" + sql); T t = sq.query(conn, sql, p); try { conn.commit(); } catch (SQLException e) { conn.rollback(); } return t; } catch (SQLException e) { throw new JdbcAccessException(e); } finally { try { conn.setAutoCommit(true); conn.close(); } catch (SQLException e) { throw new JdbcAccessException(e); } } } }