package com.ycsoft.daos.core; import static com.ycsoft.commons.helper.LoggerHelper.*; import java.util.List; import java.util.Map; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.ResultSetExtractor; import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcDaoSupport; import org.springframework.jdbc.support.JdbcUtils; import com.ycsoft.beans.system.SOptr; import com.ycsoft.daos.core.generator.SQLGenerator; import com.ycsoft.daos.core.impl.NameQueryImpl; import com.ycsoft.daos.core.impl.QueryImpl; import com.ycsoft.daos.core.mapper.ArrayMapper; import com.ycsoft.daos.core.setter.BatchPreparedStatementSetterImpl; import com.ycsoft.daos.helper.BeanHelper; /** * <p> 抽象的<tt>Session</tt>定义,主要提供了底层与<tt>Spring JDBCTemplate</tt>的封装 , * 其它如实体类的保存、更新、删除、查询等操作。需要由其子类完成!</p> * @see org.springframework.jdbc.core.namedparam.NamedParameterJdbcDaoSupport * @author hh */ public abstract class AbstractSessionSupport extends NamedParameterJdbcDaoSupport implements Session { //SQL生成器 protected SQLGenerator sqlGenerator ; /** * <p>执行更新的操作</p> * @param sql 命令 * @param params 对应占位符?参数的值 * @return 影响的行数 */ public int executeUpdate( String sql, Object ...params)throws JDBCException{ int result = getJdbcTemplate().update(sql, params ); if (isDebugEnabled(getClass())) { StringBuffer p = new StringBuffer(); p.append("update result ").append(result); p.append(sql); if (params.length > 0) { p.append("{"); for (Object s : params) { p.append(s).append(","); } p.append("}"); } debug(getClass(), p.toString()); } return result; } /** * <p> 执行sql语句结构一致的批量更新操作。当sql命令结构一致时采用该函数</p> * @param sql 命令 * @param params 参数值(多个)每一项均为数组格式分别对应命令中的占位符 * @return 查看 JDBC 批量更新的返回值 */ public int[] executeBatch(String sql , List<Object[]> params)throws JDBCException{ return getJdbcTemplate().batchUpdate( sql , new BatchPreparedStatementSetterImpl( params )); } /** * <p> 执行sql语句结构一致的批量更新操作。当sql命令结构一致时采用该函数 * ,当sql命令中只包含一个参数的时候,使用该函数</p> */ public int[] executeBatch(String sql , Object[] params)throws JDBCException{ return getJdbcTemplate().batchUpdate( sql , new BatchPreparedStatementSetterImpl( params )); } /** * <p> 批量更新已经封装好的SQL命令 </p> * @param sql * @throws JDBCException */ public int[] executeBatch(String [] sql ) throws JDBCException{ int [] result = getJdbcTemplate().batchUpdate(sql); if (isDebugEnabled(getClass())) { StringBuffer p = new StringBuffer(); for (int i=0 ;i<sql.length ;i++){ String s = sql[i]; p.append("update result ").append(result[i]).append(" ").append(s).append("\n"); } debug(getClass(), p.toString()); } return result; } /** * 按给定的SQL命名参数 ,将对应的Map中的参数值替换 * @param sql * @param params * @return * @throws JDBCException */ public int execNameParamUpdate( String sql, Map<String,?> params)throws JDBCException{ return getNamedParameterJdbcTemplate().update(sql, params); } /** * <p> SQL查询函数,会将查询的结果全部封装至对应的实体对象中<p> * @see com.ycsoft.daos.core.Query & cn.ycsoft.core.QueryImpl * @param sql SQL命令 * @param params 对应的参数值 * @return 查询接口 * @throws Exception */ public <T> Query<T> createQuery(Class<T> cls , String sql,Object... params) throws JDBCException { return new QueryImpl<T>( cls, getJdbcTemplate(), sqlGenerator, sql, params ); } /** * 创建一个自定义<code>RowMapper</code>的查询器, * @param mapper 处理结果的查询器 * @param sql 要执行的SQL命令 * @param param 可替换的参数值 * @return * @throws JDBCException */ public <T> Query<T> createQuery( RowMapper<T> mapper , String sql ,Object...params)throws JDBCException{ return new QueryImpl<T>( mapper, getJdbcTemplate(), sqlGenerator, sql, params ); } /** * 创建查询对象,SQL参数采用命名参数。 * @param paramEntity 参数实体类 * @return List集合,实体类类型为传入的T 实体类型 */ public <T> Query<T> createNameQuery( String sql , T paramEntity)throws JDBCException{ try { return new NameQueryImpl<T>( sql , getNamedParameterJdbcTemplate() , sqlGenerator , BeanHelper.describe(paramEntity), paramEntity.getClass() ); } catch (Exception e) { throw new JDBCException("创建一个查询对象失败!" , e ); } } /** * 创建查询对象,SQL参数采用命名参数。 * @param params 设置SQL命令中对应的参数名称的值到Map中传入 * @param cls 返回类型的Class */ public <T> Query<T> createNameQuery(Class<T> cls, String sql, Map<String, ?> params) throws JDBCException { return new NameQueryImpl<T>( sql , getNamedParameterJdbcTemplate() , sqlGenerator , params, cls ); } /** * <p> SQL查询函数,将查询的结果封装至集合数组中<p> * @see com.ycsoft.daos.core.Query & cn.ycsoft.core.SQLQueryImpl * @param sql SQL命令 * @param params 对应的参数值 * @return 查询接口 * @throws Exception */ public Query<Object[]> createSQLQuery(String sql,Object... params) throws JDBCException { return new QueryImpl<Object[]>( new ArrayMapper(), getJdbcTemplate(), sqlGenerator, sql, params ); } /** * 默认读取 {@link PartResultSetExtractor#DEFAULT_LIMIT}条数 * @see #queryForResult(Class, DataHandler, String, Object...) */ public <E> void queryForResult(Class<E> entityCls,DataHandler<E> dataHandler, String sql, Object...params) throws JDBCException { JdbcTemplate jt = getJdbcTemplate(); jt.setFetchSize(PartResultSetExtractor.DEFAULT_FETCH_SIZE); jt.query(sql, params, newResultSetExtractor(entityCls, dataHandler, PartResultSetExtractor.DEFAULT_LIMIT)); //this.queryForResult(entityCls, dataHandler, PartResultSetExtractor.DEFAULT_LIMIT, sql, params); } /** * <p>读取结果集,分批读取游标中的数据,读取的条数按给定limit参数,交给dataHandler回调函数处理</p> * * @param entityCls 实体类 * @param dataHandler 数据处理器 * @param limit 每次处理的条数 * @param sql 命令 * @param params sql 参数 * @throws JDBCException */ public <T> void queryForResult(Class<T> entityCls,DataHandler<T> dataHandler,int limit, String sql, Object...params) throws JDBCException { JdbcTemplate jt = getJdbcTemplate(); jt.setFetchSize(PartResultSetExtractor.DEFAULT_FETCH_SIZE); jt.query(sql, params, newResultSetExtractor(entityCls, dataHandler, limit)); } //create a PartResultSetExtractor protected <T> PartResultSetExtractor<T> newResultSetExtractor(Class<T> entityCls, DataHandler<T> dataHandler, int limit){ return new PartResultSetExtractor<T>(entityCls, dataHandler, limit); } public SQLGenerator getSqlGenerator() { return sqlGenerator; } public void setSqlGenerator(SQLGenerator sqlGenerator) { this.sqlGenerator = sqlGenerator; } }