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

org.onetwo.dbm.jdbc.internal.DbmJdbcTemplate Maven / Gradle / Ivy

package org.onetwo.dbm.jdbc.internal;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import javax.sql.DataSource;

import org.apache.commons.lang3.ArrayUtils;
import org.onetwo.common.log.JFishLoggerFactory;
import org.onetwo.dbm.jdbc.AroundPreparedStatementExecute;
import org.onetwo.dbm.jdbc.DbmListRowMapperResultSetExtractor;
import org.onetwo.dbm.jdbc.DbmNamedJdbcTemplate;
import org.onetwo.dbm.jdbc.annotation.DbmJdbcArgsMark;
import org.onetwo.dbm.jdbc.annotation.DbmJdbcOperationMark;
import org.onetwo.dbm.jdbc.annotation.DbmJdbcSqlMark;
import org.onetwo.dbm.jdbc.spi.DbmJdbcOperationType;
import org.onetwo.dbm.jdbc.spi.DbmJdbcOperations;
import org.onetwo.dbm.jdbc.spi.JdbcStatementParameterSetter;
import org.onetwo.dbm.utils.DbmUtils;
import org.slf4j.Logger;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.ArgumentTypePreparedStatementSetter;
import org.springframework.jdbc.core.CallableStatementCallback;
import org.springframework.jdbc.core.CallableStatementCreator;
import org.springframework.jdbc.core.ConnectionCallback;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.ParameterDisposer;
import org.springframework.jdbc.core.ParameterizedPreparedStatementSetter;
import org.springframework.jdbc.core.PreparedStatementCallback;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.core.PreparedStatementSetter;
import org.springframework.jdbc.core.ResultSetExtractor;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.StatementCallback;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.jdbc.support.JdbcUtils;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.util.Assert;

public class DbmJdbcTemplate extends JdbcTemplate implements DbmJdbcOperations {
	
	private final Logger logger = JFishLoggerFactory.getLogger(this.getClass());

	private final DbmListRowMapperResultSetExtractor> generatedKeysExtractor = new DbmListRowMapperResultSetExtractor>(getColumnMapRowMapper(), 1);
	protected DbmNamedJdbcTemplate dbmNamedJdbcOperations;
	private JdbcStatementParameterSetter jdbcParameterSetter;

	/*public DbmJdbcTemplate() {
	}
*/
	public DbmJdbcTemplate(DataSource dataSource) {
		this(dataSource, new SpringStatementParameterSetter());
	}
	
	public DbmJdbcTemplate(DataSource dataSource, JdbcStatementParameterSetter jdbcParameterSetter) {
		super(dataSource);
		this.jdbcParameterSetter = jdbcParameterSetter;
	}
	
	/*public void setJdbcParameterSetter(JdbcStatementParameterSetter jdbcParameterSetter) {
		this.jdbcParameterSetter = jdbcParameterSetter;
	}*/

	public void afterPropertiesSet() {
		super.afterPropertiesSet();
		this.initTemplateConfig();
	}

	protected void initTemplateConfig() {
		if(dbmNamedJdbcOperations==null){
			DbmNamedJdbcTemplate t = new DbmNamedJdbcTemplate(this);
			this.dbmNamedJdbcOperations = t;
		}
	}
	
	@Override
	public DbmNamedJdbcTemplate getDbmNamedJdbcOperations() {
		return dbmNamedJdbcOperations;
	}
	
	@Override
	@DbmJdbcOperationMark(type=DbmJdbcOperationType.UPDATE)
	public int updateWith(final SimpleArgsPreparedStatementCreator spsc, final KeyHolder generatedKeyHolder) throws DataAccessException {
		return updateWith(spsc, new AroundPreparedStatementExecute() {
			
			@Override
			public void afterExecute(PreparedStatement ps, int rows) throws SQLException {
				if(generatedKeyHolder==null)
					return ;
				List> generatedKeys = generatedKeyHolder.getKeyList();
				generatedKeys.clear();
				ResultSet keys = ps.getGeneratedKeys();
				if (keys != null) {
					try {
//						DbmListRowMapperResultSetExtractor> rse = new DbmListRowMapperResultSetExtractor>(getColumnMapRowMapper(), 1);
						generatedKeys.addAll(generatedKeysExtractor.extractData(keys));
					}
					finally {
						JdbcUtils.closeResultSet(keys);
					}
				}
				if (logger.isDebugEnabled()) {
					logger.debug("SQL update affected " + rows + " rows and returned " + generatedKeys.size() + " keys");
				}
				
			}
		});
	}

	@Override
	@DbmJdbcOperationMark(type=DbmJdbcOperationType.UPDATE)
	public int updateWith(final SimpleArgsPreparedStatementCreator spsc) throws DataAccessException {
		final PreparedStatementSetter pss = this.newArgPreparedStatementSetter(spsc.getSqlParameters());
		return update(spsc, pss);
	}
	
//	@Override
	public int updateWith(final SimpleArgsPreparedStatementCreator spsc, final AroundPreparedStatementExecute action) throws DataAccessException {
		final PreparedStatementSetter pss = this.newArgPreparedStatementSetter(spsc.getSqlParameters());
		return execute(spsc, new PreparedStatementCallback() {
			public Integer doInPreparedStatement(PreparedStatement ps) throws SQLException {
				try {
					if(action!=null)
						action.beforeExecute(pss, ps);
					else
						pss.setValues(ps);
					
					int rows = ps.executeUpdate();
					if (logger.isDebugEnabled()) {
						logger.debug("SQL update affected " + rows + " rows");
					}
					
					if(action!=null)
						action.afterExecute(ps, rows);
					
					return rows;
				}
				finally {
					if (pss instanceof ParameterDisposer) {
						((ParameterDisposer) pss).cleanupParameters();
					}
				}
			}
		});
	}
	
	
//	@Override
	public int updateWith(String sql, Object[] args, final AroundPreparedStatementExecute action) throws DataAccessException {
		SimpleArgsPreparedStatementCreator psc = new SimpleArgsPreparedStatementCreator(sql, args);
		return updateWith(psc, action);
	}
	
	@DbmJdbcOperationMark(type=DbmJdbcOperationType.BATCH_UPDATE)
	public  int[][] batchUpdateWith(@DbmJdbcSqlMark String sql, @DbmJdbcArgsMark Collection batchArgs, int batchSize) throws DataAccessException {
		int[][] ups = super.batchUpdate(sql, batchArgs, batchSize, new ParameterizedPreparedStatementSetter(){

			@Override
			public void setValues(PreparedStatement ps, T[] args) throws SQLException {
				if (args == null) {
					return ;
				}
				newArgPreparedStatementSetter(args).setValues(ps);
			}
			
		});
		return ups;
	}


	/****
	 * for update*
	 * to execute
	 * 
	 * psc SqlProvider
	 * pss SqlParametersProvider
	 */
	@Override
	protected int update(final PreparedStatementCreator psc, final PreparedStatementSetter pss) throws DataAccessException {
		return super.update(psc, pss);
	}
	
	/*****
	 * for query*
	 * to execute
	 */
	public  T query(PreparedStatementCreator psc, final PreparedStatementSetter pss, final ResultSetExtractor rse) throws DataAccessException {

		Assert.notNull(rse, "ResultSetExtractor must not be null");
		logger.debug("Executing prepared SQL query");

		return execute(psc, new PreparedStatementCallback() {
			public T doInPreparedStatement(PreparedStatement ps) throws SQLException {
				ResultSet rs = null;
				try {
					if (pss != null) {
						pss.setValues(ps);
					}
					long queryStart = System.currentTimeMillis();
					rs = ps.executeQuery();
					long quyeryEnd = System.currentTimeMillis();
					
					ResultSet rsToUse = rs;
					/*if (getNativeJdbcExtractor() != null) {
						rsToUse = getNativeJdbcExtractor().getNativeResultSet(rs);
					}*/
					
					T result = rse.extractData(rsToUse);
					
					if(logger.isDebugEnabled()){
						logger.debug("===>>> executeQuery cost time (milliseconds): " + (quyeryEnd-queryStart));
						long costTime = System.currentTimeMillis()-quyeryEnd;
						logger.debug("===>>> extractData cost time (milliseconds): " + costTime);
					}
					
					return result;
				}
				finally {
					JdbcUtils.closeResultSet(rs);
					if (pss instanceof ParameterDisposer) {
						((ParameterDisposer) pss).cleanupParameters();
					}
				}
			}
		});
	}
	

	//-------------------------------------------------------------------------
	// final execute call
	//-------------------------------------------------------------------------
	
	@Override
	public  T execute(PreparedStatementCreator psc, PreparedStatementCallback action) throws DataAccessException {
		return super.execute(psc, action);
	}
	
	@Override
	public  T execute(CallableStatementCreator csc, CallableStatementCallback action) throws DataAccessException {
		return super.execute(csc, action);
	}
	@Override
	public  T execute(StatementCallback action) throws DataAccessException {
		return super.execute(action);
	}
	

	@Override
	public  T execute(ConnectionCallback action) throws DataAccessException {
		return super.execute(action);
	}

	@Override
	protected PreparedStatementSetter newArgPreparedStatementSetter(Object[] args) {
		return new DbmArgumentPreparedStatementSetter(jdbcParameterSetter, args);
	}
	
	protected PreparedStatementSetter newArgTypePreparedStatementSetter(Object[] args, int[] argTypes) {
		return new ArgumentTypePreparedStatementSetter(args, argTypes){
			protected void doSetValue(PreparedStatement ps, int parameterPosition, int argType, Object argValue) throws SQLException {
				jdbcParameterSetter.setParameterValue(ps, parameterPosition, argType, argValue);
			}
		};
	}

	
	
	
	//------------------------------not dbmJdbcOperations----------------------------------//
	
	/****
	 * use DbmListRowMapperResultSetExtractor instead of RowMapperResultSetExtractor 
	 */
	@Override
	public  List query(String sql, RowMapper rowMapper) throws DataAccessException {
		return query(sql, new DbmListRowMapperResultSetExtractor(rowMapper));
	}

	@Override
	public  List query(PreparedStatementCreator psc, RowMapper rowMapper) throws DataAccessException {
		return query(psc, new DbmListRowMapperResultSetExtractor(rowMapper));
	}

	@Override
	@DbmJdbcOperationMark(type=DbmJdbcOperationType.QUERY)
	public  List query(@DbmJdbcSqlMark String sql, @DbmJdbcArgsMark Object[] args, RowMapper rowMapper) throws DataAccessException {
		return query(sql, args, new DbmListRowMapperResultSetExtractor(rowMapper));
	}
	
	@DbmJdbcOperationMark(type=DbmJdbcOperationType.EXECUTE)
	public void execute(@DbmJdbcSqlMark String sql) throws DataAccessException {
		super.execute(sql);
	}

	@Override
	@DbmJdbcOperationMark(type=DbmJdbcOperationType.QUERY)
	public  List query(@DbmJdbcSqlMark String sql, RowMapper rowMapper, @DbmJdbcArgsMark Object... args) throws DataAccessException {
		return query(sql, args, new DbmListRowMapperResultSetExtractor(rowMapper));
	}

	@Override
	@DbmJdbcOperationMark(type=DbmJdbcOperationType.BATCH_UPDATE)
	public int[] batchUpdate(@DbmJdbcSqlMark String sql, @DbmJdbcArgsMark Map[] batchValues) throws DataAccessException {
		return this.dbmNamedJdbcOperations.batchUpdate(sql, batchValues);
	}
	
	private int[] batchUpdateList(String sql, List> batchValues) {
		return this.dbmNamedJdbcOperations.batchUpdate(sql, DbmUtils.createBatch(batchValues));
	}
	
	@DbmJdbcOperationMark(type=DbmJdbcOperationType.BATCH_UPDATE)
	public int[] batchUpdate(@DbmJdbcSqlMark String sql, List> batchValues, int processSizePerBatch) throws DataAccessException {
		int insertSize = batchValues.size();
		if (processSizePerBatch==-1 || insertSize<=processSizePerBatch) {
			return batchUpdateList(sql, batchValues);
		}
		int startIndexInclusive = 0;
		int endIndex = 0;
		int[] res = null;
		while(endIndexinsertSize) {
				endIndex = insertSize;
			}
			List> values = batchValues.subList(startIndexInclusive, endIndex);
			int[] inserted = this.batchUpdateList(sql, values);
			res = ArrayUtils.addAll(res, inserted);
			startIndexInclusive = endIndex;
		}
		return res;
	}
	
	@DbmJdbcOperationMark(type=DbmJdbcOperationType.UPDATE)
	public int update(@DbmJdbcSqlMark String sql, @DbmJdbcArgsMark Object... args) throws DataAccessException {
		return super.update(sql, args);
	}

	@Override
	@DbmJdbcOperationMark(type=DbmJdbcOperationType.UPDATE)
	public int update(@DbmJdbcSqlMark String sql, @DbmJdbcArgsMark Map paramMap) throws DataAccessException {
		return this.dbmNamedJdbcOperations.update(sql, paramMap);
	}

	@Override
	@DbmJdbcOperationMark(type=DbmJdbcOperationType.QUERY)
	public  T query(@DbmJdbcSqlMark String sql, @DbmJdbcArgsMark Map paramMap, ResultSetExtractor rse) throws DataAccessException {
		return this.dbmNamedJdbcOperations.query(sql, paramMap, rse);
	}

	@Override
	@DbmJdbcOperationMark(type=DbmJdbcOperationType.QUERY)
	public  List query(@DbmJdbcSqlMark String sql, @DbmJdbcArgsMark Map paramMap, RowMapper rowMapper) throws DataAccessException {
		return this.dbmNamedJdbcOperations.query(sql, paramMap, rowMapper);
	}

	/****
	 * 返回结果会调用  DataAccessUtils.requiredSingleResult 过滤
	 */
	@Override
	@DbmJdbcOperationMark(type=DbmJdbcOperationType.QUERY)
	public  T queryForObject(@DbmJdbcSqlMark String sql, @DbmJdbcArgsMark Map paramMap, RowMapper rowMapper) throws DataAccessException {
		return this.dbmNamedJdbcOperations.queryForObject(sql, paramMap, rowMapper);
	}

	@Override
	@DbmJdbcOperationMark(type=DbmJdbcOperationType.EXECUTE)
	public Object execute(@DbmJdbcSqlMark String sql, @DbmJdbcArgsMark Map paramMap) throws DataAccessException {
		return this.dbmNamedJdbcOperations.execute(sql, paramMap);
	}
	
	@DbmJdbcOperationMark(type=DbmJdbcOperationType.QUERY)
	public  List queryForList(@DbmJdbcSqlMark String sql, Class elementType, @DbmJdbcArgsMark Object... args) throws DataAccessException {
		return super.queryForList(sql, elementType, args);
	}
	
	@DbmJdbcOperationMark(type=DbmJdbcOperationType.QUERY)
	public  T queryForObject(@DbmJdbcSqlMark String sql, Class requiredType, @DbmJdbcArgsMark Object... args) throws DataAccessException {
		return super.queryForObject(sql, requiredType, args);
	}
	
	@DbmJdbcOperationMark(type=DbmJdbcOperationType.QUERY)
	public  T queryForObject(@DbmJdbcSqlMark String sql, @DbmJdbcArgsMark Object[] args, RowMapper rowMapper) throws DataAccessException {
		return super.queryForObject(sql, args, rowMapper);
	}
	
	protected Connection getConnection(){
		Connection con = DataSourceUtils.getConnection(getDataSource());
		return con;
	}

	protected void closeConnection(Connection con){
		DataSourceUtils.releaseConnection(con, getDataSource());
	}
	

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy