日期:2014-05-16  浏览次数:20459 次

对jdbc的封装的总结
    记得自己刚开始学习java的时候,操作数据库都是写一大堆的代码,getXX ,setXX 的代码到处都是,而且 每次都是从ResultSet中一个个的取出数据 set到vo 中,等学习了hibernate后,由于hibernate出色的设计,已经不用再那么麻烦的写重复而繁琐的数据库操作代码。
    不过基于对初识java时候jdbc留下的深刻印象,自己业余时候对jdbc进行了下简单的封装,下面就是代码:

    用于dao继承的jdbc的封装对象 JdbcTemplate,使用的时候 继承此类即可。
   
package org.jutil.jdbc.base;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import javax.sql.DataSource;

public abstract class JdbcTemplate<T extends Object> {

	private static int commit = 100; // 每100条记录一提交
	private static boolean hasNext = false;
	private DataSource dataSource;

	/**
	 * 注入数据源
	 * 
	 * @param dataSource
	 */
	public void setDataSource(DataSource dataSource) {
		this.dataSource = dataSource;
	}

	private DataSource getDataSource() {
		return dataSource;
	}

	/**
	 * 获得接口中泛型的实例
	 * 
	 * @param index
	 * @return
	 */
	@SuppressWarnings("unchecked")
	private Class getGenericType(int index) {
		Type genType = getClass().getGenericSuperclass();
		if (!(genType instanceof ParameterizedType)) {
			return Object.class;
		}
		Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
		if (index >= params.length || index < 0) {
			throw new RuntimeException("Index outof bounds");
		}
		if (!(params[index] instanceof Class)) {
			return Object.class;
		}
		return (Class) params[index];
	}

	/**
	 * 得到Connection
	 * 
	 * @return
	 * @throws SQLException
	 */
	private Connection getConnection() throws SQLException {
		Connection connection = getDataSource() == null ? null: getDataSource().getConnection();
		return connection == null ? JdbcUtil.getInstance().getConnection(): connection;
	}

	/**
	 * 根据泛型T实体的给出的字段、查询语句、参数得到一个有数据的T实体对象
	 * 注:bean的字段名称必须与数据库查询结果列名一致
	 * 
	 * @param sql 查询语句
	 * @param args 参数
	 * @return T
	 * @throws Exception
	 */
	public T uniqueResult(String sql,Object... args) {
		return this.uniqueResult(null, null, sql, args);
	}
	
	/**
	 * 根据泛型T实体的给出的字段、查询语句、参数得到一个有数据的T实体对象
	 * 
	 * @param fieldNames 要设置值的字段
	 * @param sql 查询语句
	 * @param args 参数
	 * @return T
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public T uniqueResult(String[] fieldNames, String[] rsClums, String sql,Object... args) {
		sqlValidate(sql);
		Object obj = null;
		Connection conn = null;
		PreparedStatement pstat = null;
		ResultSet rs = null;
		try {
			conn = getConnection();
			pstat = conn.prepareStatement(sql);
			for (int i = 1; i <= args.length; i++) {
				pstat.setObject(i, args[i - 1]);
			}
			rs = pstat.executeQuery();
			if(fieldNames==null||rsClums==null){
				obj = convertObject(rs);
			}else{
				obj = convertObject(fieldNames, rsClums, rs);
			}
			pstat.close();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			free(rs, pstat, conn);
		}
		return (T) obj;
	}

	/**
	 * 执行SQL语句方法,添加,修改,删除。没有 预编译
	 * 
	 * @param sql
	 * @return
	 */
	public boolean execute(String sql, Object... args) {
		sqlValidate(sql);
		Connection conn = null;
		PreparedStatement pstat = null;
		boolean flag = false;
		try {
			conn = getConnection();
			pstat = conn.prepareStatement(sql);
			for (int i = 1; i <= args.length; i++) {
				pstat.setObject(i, args[i - 1]);
			}
			flag = pstat.execute();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			free(null, pstat, conn);
		}
		return flag;
	}

	/**
	 * 执行SQL查询语句方法,返回结果集对象
	 * 
	 * @param sql
	 * @return
	 */
	public ResultSet executeQuery(String sql, Object... args) {
		sqlValidate(sql);
		Connection conn = null;
		PreparedStatement pstat = n