package cn.hmsoft.jdbc.core;

import java.io.Writer;
import java.lang.reflect.Field;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.util.StringUtils;

import cn.hmsoft.exception.develop.PrimaryKeyLostException;
import cn.hmsoft.helper.BeanHelper;
import cn.hmsoft.jdbc.entity.DatabaseType;
import cn.hmsoft.jdbc.entity.DateFormatType;
import cn.hmsoft.jdbc.entity.Pager;
import cn.hmsoft.jdbc.entity.QueryOrder;
import cn.hmsoft.jdbc.entity.QueryOrder.QueryOrderType;
import cn.hmsoft.jdbc.entity.Table;
import cn.hmsoft.jdbc.entity.ValueCompareType;
import cn.hmsoft.jdbc.exception.ExecuteSqlException;
import cn.hmsoft.jdbc.exception.InsertNullRecordException;
import cn.hmsoft.jdbc.exception.SequenceNotExistException;
import cn.hmsoft.jdbc.generator.ISQLGenerator;
import cn.hmsoft.jdbc.generator.TableHelper;
import cn.hmsoft.jdbc.mapper.BeanMapper;
import cn.hmsoft.jdbc.mapper.MapMapper;

/*******************************
 * 对Spring的jdbc导进行封装
 * 
 * @author zxq
 * @create 2018-04-06 15:12:11
 * @version 5.0.0
 * @email: revisit@126.com
 * @Company: www.hmsoft.cn
 */
public class AbstractDaoSupport {
	@Autowired
	private ISQLGenerator sqlGenerator;
	@Autowired
	private JdbcTemplate jdbcTemplate;

	public JdbcTemplate getJdbcTemplate() {
		return this.jdbcTemplate;
	}

	public ISQLGenerator getSqlGenerator() {
		return this.sqlGenerator;
	}

	/*******************************************
	 * 统计某张表的所有数据
	 * 
	 * @param clazz
	 *            表对应的实体类
	 * @return 表的总记录数
	 */
	public int count(Class<?> clazz) {
		String sql = this.sqlGenerator.count(clazz);
		try {
			return this.jdbcTemplate.queryForObject(sql, Integer.class);
		} catch (Exception e) {
			throw new ExecuteSqlException(sql, e);
		}
	}

	/***************************
	 * 统计数据
	 */
	public <K> int count(Class<K> clazz, String columnName, Object columnValue) {
		return count(clazz, columnName, columnValue, ValueCompareType.Equal);
	}

	/***************************
	 * 统计数据
	 */
	public <K> int count(Class<K> clazz, String columnName, Object columnValue, ValueCompareType compareType) {
		String sql = this.sqlGenerator.count(clazz, columnName, compareType);
		try {
			return this.jdbcTemplate.queryForObject(sql, Integer.class, columnValue);
		} catch (Exception e) {
			throw new ExecuteSqlException(sql, e);
		}
	}

	/*******************************************
	 * 直接执行sql语句，返回收影响的记录数
	 * 
	 * @param sql
	 *            需要执行的sql语句
	 * @param objects
	 *            参数信息
	 * @return 受影响的记录数
	 */
	public int updateBySql(String sql, Object... objects) {
		try {
			return this.jdbcTemplate.update(sql, objects);
		} catch (Exception e) {
			throw new ExecuteSqlException(sql, e);
		}
	}

	/******************************************************
	 * 根据实现定义的主键删除记录
	 * 
	 * @param clazz
	 *            表对应的实体类
	 * @param keyValue
	 *            匹配值
	 * @return 返回受影响的记录数
	 */
	public int delete(Class<?> clazz, Object keyValue) {
		String sql = this.sqlGenerator.delete(clazz);
		try {
			return this.jdbcTemplate.update(sql, keyValue);
		} catch (Exception e) {
			throw new ExecuteSqlException(sql, e);
		}
	}

	/***************************************************************
	 * 根据某个字段的值删除符合条件的记录
	 * 
	 * @param clazz
	 *            表对应的实体类
	 * @param columnName
	 *            字段名称
	 * @param columnValue
	 *            配置值
	 */
	public int delete(Class<?> clazz, String columnName, Object columnValue) {
		return this.delete(clazz, columnName, columnValue, ValueCompareType.Equal);
	}

	/***************************************************************
	 * 根据某个字段的值删除符合条件的记录
	 * 
	 * @param clazz
	 *            表对应的实体类
	 * @param columnName
	 *            字段名称
	 * @param columnValue
	 *            配置值
	 */
	public int delete(Class<?> clazz, String columnName, Object columnValue, ValueCompareType compareType) {
		String sql = this.sqlGenerator.delete(clazz, columnName, compareType);
		try {
			return this.jdbcTemplate.update(sql, columnValue);
		} catch (Exception e) {
			throw new ExecuteSqlException(sql, e);
		}
	}

	/***************************************************************
	 * 根据map修改符合条件的记录
	 * 
	 * @param clazz
	 *            表对应实体类
	 * @param columnMap
	 *            待修字段map
	 * @param conditionMap
	 *            更新条件map
	 * 
	 */
	public int updateByMap(Class<?> clazz, Map<String, Object> columnMap, Map<String, Object> conditionMap) {
		String sql = this.sqlGenerator.updateByMap(clazz, columnMap, conditionMap);
		List<Object> array = new ArrayList<Object>();
		for (Object value : conditionMap.values()) {
			if (value != null)
				array.add(value);
		}
		try {
			return this.jdbcTemplate.update(sql, array.toArray(new Object[0]));
		} catch (Exception e) {
			throw new ExecuteSqlException(sql, e);
		}
	}

	/*************************
	 * 删除某张表所有数据
	 * 
	 * @param clazz
	 *            表对应的实体类
	 */
	public int deleteAll(Class<?> clazz) {
		String sql = this.sqlGenerator.deleteAll(clazz);
		try {
			return this.jdbcTemplate.update(sql);
		} catch (Exception e) {
			throw new ExecuteSqlException(sql, e);
		}
	}

	/***************************************************
	 * 往数据库插入一条数据
	 * 
	 * @param entity
	 */
	public Integer insert(Object entity) {
		Integer keyValue = null;
		if (entity == null)
			throw new InsertNullRecordException();
		boolean seq_flag = true;
		Class<?> clazz = entity.getClass();
		Map<String, Object> paramMap = BeanHelper.toMap(entity);
		Table table = TableHelper.getTable(clazz);
		Field field = null;
		if (!StringUtils.isEmpty(table.keyColumn()) && !StringUtils.isEmpty(table.sequenceName())) {
			try {
				field = clazz.getDeclaredField(table.keyColumn().toLowerCase());
				field.setAccessible(true);
			} catch (Exception e) {
			}
			if (field == null)
				throw new PrimaryKeyLostException(clazz);
			Object value = null;
			try {
				value = field.get(entity);
			} catch (Exception e) {
				throw new PrimaryKeyLostException(clazz);
			}
			if (value == null) {
				// 需要去获取序列
				if (JdbcProperty.DATABAETYPE == DatabaseType.Oracle) {
					seq_flag = false;
					// 除mysql外，走sequence模式
					keyValue = this.getNextSequence(table.sequenceName());
					paramMap.put(field.getName(), keyValue);
					// 设置主键值
					BeanHelper.setFiledValue(entity, field, keyValue);
				}
			} else {
				seq_flag = false;
			}
		} else {
			seq_flag = false;
		}
		String sql = this.sqlGenerator.insert(clazz, paramMap);

		MapSqlParameterSource source = new MapSqlParameterSource(paramMap);
		try {
			KeyHolder keyHolder = new GeneratedKeyHolder();
			new NamedParameterJdbcTemplate(this.jdbcTemplate.getDataSource()).update(sql, source, keyHolder);
			if (seq_flag == true) {
				keyValue = keyHolder.getKey().intValue();
				// 设置主键值
				BeanHelper.setFiledValue(entity, field, keyValue);
				// System.out.println(field.getName()+":"+keyValue);
			}
		} catch (Exception e) {
			throw new ExecuteSqlException(sql, e);
		}
		return keyValue;
	}

	/********************************************
	 * 更新单条记录
	 */
	public void update(Object entity) {
		Map<String, Object> paramMap = BeanHelper.toMap(entity);
		String sql = this.sqlGenerator.update(entity.getClass(), paramMap);
		try {
			new NamedParameterJdbcTemplate(this.jdbcTemplate.getDataSource()).update(sql, paramMap);
		} catch (Exception e) {
			throw new ExecuteSqlException(sql, e);
		}
	}

	/*****************************************
	 * 执行执行sql语句，返回受影响的记录数
	 * 
	 * @param sql
	 */
	public int updateBySql(String sql) {
		try {
			return this.jdbcTemplate.update(sql);
		} catch (Exception e) {
			throw new ExecuteSqlException(sql, e);
		}
	}

	/*****
	 * 根据sql查询单个简单值，如String Integer
	 * 
	 * @param args
	 */
	public <K> K findObject(Class<K> clazz, String sql, Object... args) {
		try {
			return this.jdbcTemplate.queryForObject(sql, clazz, args);
		} catch (Exception e) {
			throw new ExecuteSqlException(sql, e);
		}
	}

	/***************************************
	 * 根据sql语句查询符合记录的数据
	 */
	public <K> List<K> listBySql(Class<K> clazz, String sql, Object... args) {
		try {
			return this.jdbcTemplate.query(sql, new BeanMapper<K>(clazz), args);
		} catch (Exception e) {
			throw new ExecuteSqlException(sql, e);
		}
	}

	/***************************************
	 * 根据sql语句查询符合记录的数据
	 */
	public <K> List<K> listBySql(Class<K> clazz, QueryOrder order, String sql, Object... args) {
		String vSql = this.sqlGenerator.list(sql, 0, Integer.MAX_VALUE, order);
		try {
			return this.jdbcTemplate.query(vSql, new BeanMapper<K>(clazz), args);
		} catch (Exception e) {
			throw new ExecuteSqlException(vSql, e);
		}
	}

	/***************************************
	 * 根据sql语句查询符合记录的数据
	 */
	public <K> List<K> listBySql(Class<K> clazz, int start, int limit, String sql, Object... args) {
		String limitSql = this.sqlGenerator.list(sql, start, limit);
		try {
			return this.jdbcTemplate.query(limitSql, new BeanMapper<K>(clazz), args);
		} catch (Exception e) {
			throw new ExecuteSqlException(sql, e);
		}
	}

	/***************************************
	 * 根据sql语句查询符合记录的数据
	 */
	public <K> List<K> listBySql(Class<K> clazz, QueryOrder order, int start, int limit, String sql, Object... args) {
		String limitSql = this.sqlGenerator.list(sql, start, limit, order);
		try {
			return this.jdbcTemplate.query(limitSql, new BeanMapper<K>(clazz), args);
		} catch (Exception e) {
			throw new ExecuteSqlException(sql, e);
		}
	}

	/***************************************
	 * 根据sql语句查询符合记录的数据
	 */
	public List<Map<String, Object>> listMapBySql(String sql, Object... args) {
		try {
			return this.jdbcTemplate.query(sql, new MapMapper(), args);
		} catch (Exception e) {
			throw new ExecuteSqlException(sql, e);
		}
	}

	/***************************************
	 * 根据sql语句查询符合记录的数据
	 */
	public List<Map<String, Object>> listMapBySql(Object[] args, String sql) {
		try {

			return this.jdbcTemplate.query(sql, args, new MapMapper());
		} catch (Exception e) {
			throw new ExecuteSqlException(sql, e);
		}
	}

	/*******************************
	 * 根据sql语句查询符合记录的数据
	 */
	public List<Map<String, Object>> listMapBySql(QueryOrder order, int start, int limit, String sql, Object... args) {
		String limitSql = this.sqlGenerator.list(sql, start, limit, order);
		try {
			return this.jdbcTemplate.query(limitSql, new MapMapper(), args);
		} catch (Exception e) {
			throw new ExecuteSqlException(sql, e);
		}
	}

	/*****************************************
	 * 查询符合某条件的记录
	 */
	public <K> List<K> list(Class<K> clazz, String columnName, Object columnValue) {
		return this.list(clazz, columnName, columnValue, ValueCompareType.Equal);
	}

	/*****************************************
	 * 查询符合某条件的记录
	 */
	public <K> List<K> list(Class<K> clazz, String columnName, Object columnValue, QueryOrder queryOrder) {
		return this.list(clazz, columnName, columnValue, ValueCompareType.Equal, queryOrder);
	}

	/*****************************************
	 * 查询符合某条件的记录
	 */
	public <K> List<K> list(Class<K> clazz, String columnName, Object columnValue, ValueCompareType compareType) {
		return this.list(clazz, columnName, columnValue, compareType, null);
	}

	/*****************************************
	 * 查询符合某条件的记录
	 */
	public <K> List<K> list(Class<K> clazz, String columnName, Object columnValue, ValueCompareType compareType,
			QueryOrder queryOrder) {
		String sql = this.sqlGenerator.list(clazz, columnName, queryOrder);
		try {
			return this.jdbcTemplate.query(sql, new BeanMapper<K>(clazz), columnValue);
		} catch (Exception e) {
			throw new ExecuteSqlException(sql, e);
		}
	}

	/*****************************************
	 * 查询符合某条件的记录
	 */
	public <K> List<K> list(Class<K> clazz, String columnName, Object columnValue, int start, int limit) {
		return this.list(clazz, columnName, columnValue, ValueCompareType.Equal, start, limit, null);
	}

	/*****************************************
	 * 查询符合某条件的记录
	 */
	public <K> List<K> list(Class<K> clazz, String columnName, Object columnValue, QueryOrder order, int start,
			int limit) {
		return this.list(clazz, columnName, columnValue, ValueCompareType.Equal, start, limit, order);
	}

	public <K> List<K> list(Class<K> clazz, String columnName, Object columnValue, ValueCompareType compareType,
			int start, int limit, QueryOrder queryOrder) {
		String sql = this.sqlGenerator.list(this.sqlGenerator.list(clazz, columnName, compareType, queryOrder), start,
				limit);
		try {
			return this.jdbcTemplate.query(sql, new BeanMapper<K>(clazz), columnValue);
		} catch (Exception e) {
			throw new ExecuteSqlException(sql, e);
		}
	}

	public <K> List<K> all(Class<K> clazz) {
		String sql = this.sqlGenerator.all(clazz);
		try {
			return this.jdbcTemplate.query(sql, new BeanMapper<K>(clazz));
		} catch (Exception e) {
			throw new ExecuteSqlException(sql, e);
		}
	}

	public <K> List<K> all(Class<K> clazz, QueryOrder order) {
		String sql = this.sqlGenerator.all(clazz, order);
		try {
			return this.jdbcTemplate.query(sql, new BeanMapper<K>(clazz));
		} catch (Exception e) {
			throw new ExecuteSqlException(sql, e);
		}
	}

	public <K> List<K> all(Class<K> clazz, int start, int limit) {
		String sqlLimit = this.sqlGenerator.list(this.sqlGenerator.all(clazz), start, limit);
		try {
			return this.jdbcTemplate.query(sqlLimit, new BeanMapper<K>(clazz));
		} catch (Exception e) {
			throw new ExecuteSqlException(sqlLimit);
		}
	}

	public <K> List<K> all(Class<K> clazz, int start, int limit, QueryOrder order) {
		String sqlLimit = this.sqlGenerator.list(this.sqlGenerator.all(clazz, order), start, limit);
		try {
			return this.jdbcTemplate.query(sqlLimit, new BeanMapper<K>(clazz));
		} catch (Exception e) {
			throw new ExecuteSqlException(sqlLimit);
		}
	}

	public Pager page(Class<?> clazz, int start, int limit) {
		String sql = this.sqlGenerator.all(clazz);
		String countSql = this.sqlGenerator.count(sql);
		try {
			int total = this.jdbcTemplate.queryForObject(countSql, Integer.class);
			return new Pager(this.all(clazz, start, limit), total, start, limit);
		} catch (Exception e) {
			throw new ExecuteSqlException(sql, e);
		}
	}

	/*****
	 * 分页查询一张表的所有记录
	 */
	public Pager page(Class<?> clazz, int start, int limit, QueryOrder queryOrder) {
		String sql = this.sqlGenerator.all(clazz, queryOrder);
		String countSql = this.sqlGenerator.count(sql);
		try {
			int total = this.jdbcTemplate.queryForObject(countSql, Integer.class);
			return new Pager(this.all(clazz, start, limit, queryOrder), total, start, limit);
		} catch (Exception e) {
			throw new ExecuteSqlException(sql, e);
		}
	}

	/*****
	 * 根据单一字段分页查询记录
	 */
	public Pager pageByColumn(Class<?> clazz, String columnName, Object columnValue, int start, int limit) {
		return this.pageByColumn(clazz, columnName, columnValue, ValueCompareType.Equal, start, limit, null);
	}

	/*****
	 * 根据单一字段分页查询记录
	 */
	public Pager pageByColumn(Class<?> clazz, String columnName, Object columnValue, int start, int limit,
			QueryOrder queryOrder) {
		return this.pageByColumn(clazz, columnName, columnValue, ValueCompareType.Equal, start, limit, queryOrder);
	}

	/*****
	 * 根据单一字段分页查询记录
	 */
	public Pager pageByColumn(Class<?> clazz, String columnName, Object columnValue, ValueCompareType compareType,
			int start, int limit, QueryOrder queryOrder) {
		String sql = this.sqlGenerator.list(clazz, columnName, compareType, queryOrder);
		String countSql = this.sqlGenerator.count(sql);
		try {
			int total = this.jdbcTemplate.queryForObject(countSql, Integer.class, columnName);
			return new Pager(this.list(clazz, columnName, columnValue, compareType, start, limit, queryOrder), total,
					start, limit);
		} catch (Exception e) {
			throw new ExecuteSqlException(sql, e);
		}
	}

	/*****
	 * 根据sql分页查询记录
	 */
	public Pager pageBySql(Class<?> clazz, int start, int limit, String sql, Object... args) {
		String countSql = this.sqlGenerator.count(sql);
		try {
			int total = this.jdbcTemplate.queryForObject(countSql, Integer.class, args);
			return new Pager(this.listBySql(clazz, start, limit, sql, args), total, start, limit);
		} catch (Exception e) {
			throw new ExecuteSqlException(sql, e);
		}
	}

	public Pager pageBySql(Class<?> clazz, QueryOrder order, int start, int limit, String sql, Object... args) {
		String countSql = this.sqlGenerator.count(sql);
		try {
			int total = this.jdbcTemplate.queryForObject(countSql, Integer.class, args);
			return new Pager(this.listBySql(clazz, order, start, limit, sql, args), total, start, limit);
		} catch (Exception e) {
			// e.printStackTrace();
			throw new ExecuteSqlException(sql, e);
		}
	}

	/*****
	 * 根据sql分页查询记录
	 */
	public Pager pageMapBySql(int start, int limit, String sql, Object... args) {
		String countSql = this.sqlGenerator.count(sql);
		try {
			int total = this.jdbcTemplate.queryForObject(countSql, Integer.class, args);
			return new Pager(this.listMapBySql(null, start, limit, sql, args), total, start, limit);
		} catch (Exception e) {
			throw new ExecuteSqlException(sql, e);
		}
	}

	public Pager pageMapBySql(QueryOrder order, int start, int limit, String sql, Object... args) {
		String countSql = this.sqlGenerator.count(sql);
		try {
			int total = this.jdbcTemplate.queryForObject(countSql, Integer.class, args);
			return new Pager(this.listMapBySql(order, start, limit, sql, args), total, start, limit);
		} catch (Exception e) {
			throw new ExecuteSqlException(sql, e);
		}
	}

	/*************************
	 * 根据主键值查找记录
	 * 
	 * @param clazz
	 * @param keyValue
	 *            主键值
	 * @return
	 */
	public <K> K find(Class<K> clazz, Object keyValue) {
		String sql = this.sqlGenerator.find(clazz);
		try {
			List<K> list = this.listBySql(clazz, sql, keyValue);
			return list.size() > 0 ? list.get(0) : null;
		} catch (Exception e) {
			throw new ExecuteSqlException(sql, e);
		}
	}

	/*****
	 * 根据某一个字段值，读取第一行数据
	 */
	public <K> K find(Class<K> clazz, String columnName, Object columnValue) {
		return this.find(clazz, columnName, columnValue, ValueCompareType.Equal, null);
	}

	/*****
	 * 根据某一个字段值和排序条件，读取第一行数据
	 * 
	 * @param clazz
	 * @param columnName
	 * @param columnValue
	 */
	public <K> K find(Class<K> clazz, String columnName, Object columnValue, QueryOrder queryOrder) {
		return this.find(clazz, columnName, columnValue, ValueCompareType.Equal, queryOrder);
	}

	public <K> K find(Class<K> clazz, String columnName, Object columnValue, ValueCompareType compareType,
			QueryOrder queryOrder) {
		String sql = this.sqlGenerator.list(clazz, 0, 1, columnName, compareType, queryOrder);
		try {
			List<K> list = this.listBySql(clazz, sql, columnValue);
			return list.size() > 0 ? list.get(0) : null;
		} catch (Exception e) {
			throw new ExecuteSqlException(sql, e);
		}
	}

	/*****
	 * 根据sql语句获取符合条件的第一条记录
	 */
	public <K> K findBySql(Class<K> clazz, String sql, Object... args) {
		try {
			List<K> list = this.listBySql(clazz, 0, 1, sql, args);
			if (list.size() == 0)
				return null;
			return list.get(0);
		} catch (Exception e) {
			throw new ExecuteSqlException(sql, e);
		}
	}

	/*****
	 * 根据sql语句获取符合条件的第一条记录
	 */
	public Map<String, Object> findMapBySql(String sql, Object... args) {
		try {
			List<Map<String, Object>> list = this.listMapBySql(new QueryOrder(""), 0, 1, sql, args);
			if (list.size() == 0)
				return null;
			return list.get(0);
		} catch (Exception e) {
			throw new ExecuteSqlException(sql, e);
		}
	}

	/***************************************************
	 * 获取序列的下一个值
	 * 
	 * @param sequenceName
	 *            序列名称
	 * @return
	 */
	public Integer getNextSequence(String sequenceName) {
		String[] array = this.sqlGenerator.getNextSequence(sequenceName);
		// 依次执行sql语句,最有一个sql语句返回序列,最后一条不在循环中
		int keyValue = 0;
		synchronized (sequenceName) {
			for (int i = 0; i < array.length - 1; i++)
				this.jdbcTemplate.execute(array[i]);
			// 最有一句sql语句获得seq
			try {
				keyValue = this.jdbcTemplate.queryForObject(array[array.length - 1], Integer.class);
			} catch (Exception e) {
				throw new SequenceNotExistException(sequenceName);
			}
		}
		return keyValue;
	}

	/********************************************
	 * 设置oracle CLOB字段的值
	 * 
	 * @param clazz
	 *            表对应的实体类
	 * @param keyValue
	 *            主键对应的值
	 * @param columnName
	 *            CLOB字段的名称
	 * @param columnValue
	 *            需要设置的值
	 */
	@SuppressWarnings("deprecation")
	public <K> void setClobColumn(Class<K> clazz, Object keyValue, String columnName, String columnValue) {
		Table table = this.sqlGenerator.getTable(clazz);
		// 先update
		String sql = "";
		try {
			sql = "update " + table.tableName() + " set " + columnName + " = empty_clob() where " + table.keyColumn()
					+ " = ?";
			this.jdbcTemplate.update(sql, keyValue);
			sql = "select " + columnName + " from " + table.tableName() + " where  " + table.keyColumn()
					+ " = ? for update";
			Connection conn = DataSourceUtils.getConnection(this.jdbcTemplate.getDataSource());
			PreparedStatement stmt = conn.prepareStatement(sql); // java.sql.Connection
			stmt.setObject(1, keyValue);
			ResultSet rset = stmt.executeQuery();// java.sql.ResultSet
			oracle.sql.CLOB clob = null;
			if (rset.next())
				clob = (oracle.sql.CLOB) rset.getClob(1); // java.sql.Blob
			else {
				stmt.close();
				conn.commit();
				return;
			}
			rset.close();
			Writer outStream = clob.getCharacterOutputStream();
			char[] c = columnValue.toCharArray();
			outStream.write(c, 0, c.length);
			outStream.flush();
			outStream.close();
			stmt.close();
			sql = "update " + table.tableName() + " set " + columnName + " = ? where " + table.keyColumn() + " = ?";
			stmt = conn.prepareStatement(sql);
			stmt.setClob(1, clob);
			stmt.setObject(2, keyValue);
			stmt.executeUpdate();
			stmt.close();
			// conn.commit();// 前面设置conn.setAutoCommit(false)所以这里勿忘手动提交！

		} catch (Exception e) {
			throw new ExecuteSqlException(sql, e);
		}
	}

	/********************************************
	 * 获取CLOB字段的值(Oracle)
	 * 
	 * @param clazz
	 *            表对应的实体
	 * @param keyValue
	 *            主键值
	 * @param columnName
	 *            CLOB字段名称
	 * @return
	 */
	public <K> String getClobColumn(Class<K> clazz, final Object keyValue, String columnName) {
		String sql = this.sqlGenerator.queryBlob(clazz, columnName);
		List<String> list = this.jdbcTemplate.query(sql, new Object[] { keyValue }, new RowMapper<String>() {
			public String mapRow(ResultSet rs, int rowNum) throws SQLException {
				Clob clob = rs.getClob(1);
				if (clob != null) {
					long len = clob.length();
					return clob.getSubString(1, (int) len);
				}
				return null;

			}
		});
		return (list == null || list.size() == 0) ? null : list.get(0);
	}

	@SuppressWarnings("unchecked")
	public <K> List<K> listObject(final Class<K> clazz, String sql, Object... args) {
		List<K> list = this.jdbcTemplate.query(sql, args, new RowMapper<K>() {
			public K mapRow(ResultSet rs, int rowNum) throws SQLException {
				return (K) rs.getObject(1);
			}
		});
		return list;
	}

	/**************************
	 * 生成like参数
	 */
	public String generateLikeParamter(String value) {
		return this.sqlGenerator.like(value);
	}

	/****************
	 * ISNULL,默认值为指定值
	 */
	public String isNull(String columnName) {
		return this.sqlGenerator.isNull(columnName);
	}

	/****************
	 * ISNULL,默认值为某个字段
	 */
	public String isNullWithColumn(String columnName, String otherColumnName) {
		return this.sqlGenerator.isNull(columnName, otherColumnName);
	}
	/*********************
	 * 合并
	 */
	public String concatValues(String columnName) {
		return this.sqlGenerator.concatValues(columnName);

	}

	
	/**********************
	 * 日期格式化
	 */
	public String formatDate(String columnName, DateFormatType format) {
		return this.sqlGenerator.formatDate(columnName, format);
	}
	/**************************
	 * 生成随机数
	 */
	public String random() {
		return this.sqlGenerator.random();
	}

	/**************************
	 * 生成排序参数
	 */
	public static QueryOrder generateQueryOrder(String order, String type) {
		if (StringUtils.isEmpty(order))
			return null;
		if (StringUtils.isEmpty(type) || type.toLowerCase().toString().equals("asc"))
			return new QueryOrder(order, QueryOrderType.ASC);
		return new QueryOrder(order, QueryOrderType.DESC);
	}

}
