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

com.gitee.qdbp.jdbc.biz.SqlBufferJdbcTemplate Maven / Gradle / Ivy

package com.gitee.qdbp.jdbc.biz;

import java.net.URL;
import java.sql.Connection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.sql.DataSource;
import com.gitee.qdbp.able.exception.ServiceException;
import com.gitee.qdbp.able.result.IResultMessage;
import com.gitee.qdbp.able.result.ResultCode;
import com.gitee.qdbp.jdbc.api.SqlBufferJdbcOperations;
import com.gitee.qdbp.jdbc.model.DbVersion;
import com.gitee.qdbp.jdbc.plugins.DbPluginContainer;
import com.gitee.qdbp.jdbc.plugins.DbPluginHelper;
import com.gitee.qdbp.jdbc.plugins.SqlDialect;
import com.gitee.qdbp.jdbc.result.FirstColumnMapper;
import com.gitee.qdbp.jdbc.result.RowToBeanMapper;
import com.gitee.qdbp.jdbc.sql.SqlBuffer;
import com.gitee.qdbp.jdbc.utils.CountSqlParser;
import com.gitee.qdbp.tools.files.PathTools;
import com.gitee.qdbp.tools.utils.ConvertTools;
import com.gitee.qdbp.tools.utils.ReflectTools;
import com.gitee.qdbp.tools.utils.StringTools;
import com.gitee.qdbp.tools.utils.VerifyTools;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.JdbcOperations;
import org.springframework.jdbc.core.PreparedStatementCallback;
import org.springframework.jdbc.core.ResultSetExtractor;
import org.springframework.jdbc.core.RowCallbackHandler;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
import org.springframework.jdbc.core.namedparam.NamedParameterUtils;
import org.springframework.jdbc.core.namedparam.ParsedSql;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.jdbc.datasource.init.ScriptUtils;
import org.springframework.jdbc.support.JdbcAccessor;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.jdbc.support.rowset.SqlRowSet;

/**
 * SqlBuffer数据库操作类
 *
 * @author 赵卉华
 * @version 190601
 */
public class SqlBufferJdbcTemplate implements SqlBufferJdbcOperations {

    private static final Logger log = LoggerFactory.getLogger(SqlBufferJdbcTemplate.class);

    protected final CountSqlParser countSqlParser;
    private final NamedParameterJdbcOperations namedJdbcOperations;
    private final DbPluginHelper plugins;
    private DbVersion dbVersion;
    private SqlDialect sqlDialect;

    public SqlBufferJdbcTemplate(NamedParameterJdbcOperations jdbc, DbPluginContainer plugins) {
        this.namedJdbcOperations = jdbc;
        this.plugins = plugins.helper();
        this.countSqlParser = new CountSqlParser();
    }

    protected SqlBufferJdbcTemplate(SqlBufferJdbcTemplate parent) {
        this.plugins = parent.plugins;
        this.namedJdbcOperations = parent.namedJdbcOperations;
        this.countSqlParser = parent.countSqlParser;
        this.dbVersion = parent.dbVersion;
        this.sqlDialect = parent.sqlDialect;
    }

    @Override
    public DbPluginHelper plugins() {
        return plugins;
    }

    @Override
    public DbVersion dbVersion() {
        initDialect();
        return dbVersion;
    }

    @Override
    public SqlDialect sqlDialect() {
        initDialect();
        return sqlDialect;
    }

    private void initDialect() {
        if (this.sqlDialect == null) {
            this.doInitDialect();
        }
    }

    private synchronized void doInitDialect() {
        if (this.sqlDialect == null) {
            JdbcOperations jdbcOperations = namedJdbcOperations.getJdbcOperations();
            if (!(jdbcOperations instanceof JdbcAccessor)) {
                throw new IllegalStateException("Unsupported JdbcOperations: " + jdbcOperations.getClass().getName());
            }
            JdbcAccessor accessor = (JdbcAccessor) jdbcOperations;
            DataSource datasource = accessor.getDataSource();
            if (datasource == null) {
                throw new IllegalStateException("Datasource is null.");
            }
            this.dbVersion = plugins.findDbVersion(datasource);
            this.sqlDialect = plugins.buildSqlDialect(dbVersion);
            log.debug("Database version: {}", dbVersion);
        }
    }

    protected RowMapper> getRowToMapConverter() {
        return plugins.getRowToMapConverter();
    }

    protected  RowToBeanMapper getRowToBeanConverter(Class clazz) {
        return plugins.getRowToBeanMapper(clazz);
    }

    @Override
    public  T execute(SqlBuffer sb, PreparedStatementCallback action) throws ServiceException {
        VerifyTools.requireNotBlank(sb, "sqlBuffer");
        long startTime = System.currentTimeMillis();
        String logsql = null;
        if (log.isDebugEnabled()) {
            log.debug("Executing sql statement:\n{}", logsql = getFormattedSqlString(sb, 1));
        }
        String sql = getPreparedSqlString(sb);
        Map params = sb.getPreparedVariables();
        try {
            T result = namedJdbcOperations.execute(sql, params, action);
            if (log.isDebugEnabled()) {
                long time = System.currentTimeMillis() - startTime;
                log.debug("Sql query returns {} rows, elapsed time {}ms.", result == null ? 0 : 1, time);
            }
            return result;
        } catch (EmptyResultDataAccessException e) {
            if (log.isDebugEnabled()) {
                log.debug("Sql query returns 0 row.");
            }
            return null;
        } catch (DataAccessException e) {
            String details = "Sql:\n" + (logsql != null ? logsql : getFormattedSqlString(sb, 1));
            throw createServiceException(ResultCode.DB_SELECT_ERROR, details, e);
        }
    }

    @Override
    public  T query(SqlBuffer sb, ResultSetExtractor rse) throws ServiceException {
        VerifyTools.requireNotBlank(sb, "sqlBuffer");
        long startTime = System.currentTimeMillis();
        String logsql = null;
        if (log.isDebugEnabled()) {
            log.debug("Executing sql query:\n{}", logsql = getFormattedSqlString(sb, 1));
        }
        String sql = getPreparedSqlString(sb);
        Map params = sb.getPreparedVariables();
        try {
            T result = namedJdbcOperations.query(sql, params, rse);
            if (log.isDebugEnabled()) {
                long time = System.currentTimeMillis() - startTime;
                log.debug("Sql query returns {} rows, elapsed time {}ms.", result == null ? 0 : 1, time);
            }
            return result;
        } catch (EmptyResultDataAccessException e) {
            if (log.isDebugEnabled()) {
                long time = System.currentTimeMillis() - startTime;
                log.debug("Sql query returns 0 row, elapsed time {}ms.", time);
            }
            return null;
        } catch (DataAccessException e) {
            String details = "Sql:\n" + (logsql != null ? logsql : getFormattedSqlString(sb, 1));
            throw createServiceException(ResultCode.DB_SELECT_ERROR, details, e);
        }
    }

    @Override
    public void query(SqlBuffer sb, RowCallbackHandler rch) throws ServiceException {
        VerifyTools.requireNotBlank(sb, "sqlBuffer");
        long startTime = System.currentTimeMillis();
        String logsql = null;
        if (log.isDebugEnabled()) {
            log.debug("Executing sql query:\n{}", logsql = getFormattedSqlString(sb, 1));
        }
        String sql = getPreparedSqlString(sb);
        Map params = sb.getPreparedVariables();
        try {
            namedJdbcOperations.query(sql, params, rch);
            if (log.isDebugEnabled()) {
                long time = System.currentTimeMillis() - startTime;
                log.debug("Sql query, elapsed time {}ms.", time);
            }
        } catch (DataAccessException e) {
            String details = "Sql:\n" + (logsql != null ? logsql : getFormattedSqlString(sb, 1));
            throw createServiceException(ResultCode.DB_SELECT_ERROR, details, e);
        }
    }

    @Override
    public  List query(SqlBuffer sb, RowMapper rowMapper) throws ServiceException {
        VerifyTools.requireNotBlank(sb, "sqlBuffer");
        long startTime = System.currentTimeMillis();
        String logsql = null;
        if (log.isDebugEnabled()) {
            log.debug("Executing sql query:\n{}", logsql = getFormattedSqlString(sb, 1));
        }
        String sql = getPreparedSqlString(sb);
        Map params = sb.getPreparedVariables();
        try {
            List list = namedJdbcOperations.query(sql, params, rowMapper);
            if (log.isDebugEnabled()) {
                long time = System.currentTimeMillis() - startTime;
                log.debug("Sql query returns {} rows, elapsed time {}ms.", list == null ? 0 : list.size(), time);
            }
            return list;
        } catch (DataAccessException e) {
            String details = "Sql:\n" + (logsql != null ? logsql : getFormattedSqlString(sb, 1));
            throw createServiceException(ResultCode.DB_SELECT_ERROR, details, e);
        }
    }

    @Override
    public  T queryForObject(SqlBuffer sb, RowMapper rowMapper) throws ServiceException {
        VerifyTools.requireNotBlank(sb, "sqlBuffer");
        long startTime = System.currentTimeMillis();
        String logsql = null;
        if (log.isDebugEnabled()) {
            log.debug("Executing sql query:\n{}", logsql = getFormattedSqlString(sb, 1));
        }
        String sql = getPreparedSqlString(sb);
        Map params = sb.getPreparedVariables();
        try {
            T result = namedJdbcOperations.queryForObject(sql, params, rowMapper);
            if (log.isDebugEnabled()) {
                long time = System.currentTimeMillis() - startTime;
                log.debug("Sql query returns {} rows, elapsed time {}ms.", result == null ? 0 : 1, time);
            }
            return result;
        } catch (EmptyResultDataAccessException e) {
            if (log.isDebugEnabled()) {
                long time = System.currentTimeMillis() - startTime;
                log.debug("Sql query returns 0 row, elapsed time {}ms.", time);
            }
            return null;
        } catch (DataAccessException e) {
            String details = "Sql:\n" + (logsql != null ? logsql : getFormattedSqlString(sb, 1));
            throw createServiceException(ResultCode.DB_SELECT_ERROR, details, e);
        }
    }

    @Override
    public  T queryForObject(SqlBuffer sb, Class resultType) throws ServiceException {
        VerifyTools.requireNotBlank(sb, "sqlBuffer");
        if (!ReflectTools.isPrimitive(resultType, false)) {
            return queryForObject(sb, getRowToBeanConverter(resultType));
        }
        long startTime = System.currentTimeMillis();
        String logsql = null;
        if (log.isDebugEnabled()) {
            log.debug("Executing sql query:\n{}", logsql = getFormattedSqlString(sb, 1));
        }
        String sql = getPreparedSqlString(sb);
        Map params = sb.getPreparedVariables();
        try {
            T result = namedJdbcOperations.queryForObject(sql, params, resultType);
            if (log.isDebugEnabled()) {
                long time = System.currentTimeMillis() - startTime;
                queryForObjectLogResult(time, result);
            }
            return result;
        } catch (EmptyResultDataAccessException e) {
            if (log.isDebugEnabled()) {
                long time = System.currentTimeMillis() - startTime;
                log.debug("Sql query returns 0 row, elapsed time {}ms.", time);
            }
            return null;
        } catch (DataAccessException e) {
            String details = "Sql:\n" + (logsql != null ? logsql : getFormattedSqlString(sb, 1));
            throw createServiceException(ResultCode.DB_SELECT_ERROR, details, e);
        }
    }

    private void queryForObjectLogResult(long time, Object result) {
        if (result == null) {
            log.debug("Sql query returns 0 row, elapsed time {}ms.", time);
            return;
        }
        Class resultType = result.getClass();
        if (resultType == String.class) {
            String string = (String) result;
            String desc = string.length() > 100 ? "String(" + string.length() + ")" : string;
            log.debug("Sql query returns 1 row, the value is {}, elapsed time {}ms.", desc, time);
        } else if (ReflectTools.isPrimitive(resultType) || resultType.isEnum()) {
            String string = result.toString();
            log.debug("Sql query returns 1 row, the value is {}, elapsed time {}ms.", string, time);
        } else {
            log.debug("Sql query returns 1 row, elapsed time {}ms.", time);
        }
    }

    @Override
    public Map queryForMap(SqlBuffer sb) throws ServiceException {
        RowMapper> rowToMapConverter = getRowToMapConverter();
        return queryForMap(sb, rowToMapConverter);
    }

    @Override
    public Map queryForMap(SqlBuffer sb, RowMapper> rowMapper)
            throws ServiceException {
        VerifyTools.requireNotBlank(sb, "sqlBuffer");
        long startTime = System.currentTimeMillis();
        String logsql = null;
        if (log.isDebugEnabled()) {
            log.debug("Executing sql query:\n{}", logsql = getFormattedSqlString(sb, 1));
        }
        String sql = getPreparedSqlString(sb);
        Map params = sb.getPreparedVariables();
        try {
            Map result = namedJdbcOperations.queryForObject(sql, params, rowMapper);
            if (log.isDebugEnabled()) {
                long time = System.currentTimeMillis() - startTime;
                log.debug("Sql query returns {} rows, elapsed time {}ms.", result == null ? 0 : 1, time);
            }
            return result;
        } catch (EmptyResultDataAccessException e) {
            if (log.isDebugEnabled()) {
                long time = System.currentTimeMillis() - startTime;
                log.debug("Sql query returns 0 row, elapsed time {}ms.", time);
            }
            return null;
        } catch (DataAccessException e) {
            String details = "Sql:\n" + (logsql != null ? logsql : getFormattedSqlString(sb, 1));
            throw createServiceException(ResultCode.DB_SELECT_ERROR, details, e);
        }
    }

    @Override
    public  List queryForList(SqlBuffer sb, Class elementType) throws ServiceException {
        VerifyTools.requireNotBlank(sb, "sqlBuffer");
        long startTime = System.currentTimeMillis();
        String logsql = null;
        if (log.isDebugEnabled()) {
            log.debug("Executing sql query:\n{}", logsql = getFormattedSqlString(sb, 1));
        }
        String sql = getPreparedSqlString(sb);
        Map params = sb.getPreparedVariables();
        try {
            List list;
            if (ReflectTools.isPrimitive(elementType, false)) {
                list = namedJdbcOperations.queryForList(sql, params, elementType);
            } else {
                list = namedJdbcOperations.query(sql, params, getRowToBeanConverter(elementType));
            }
            if (log.isDebugEnabled()) {
                long time = System.currentTimeMillis() - startTime;
                log.debug("Sql query returns {} rows, elapsed time {}ms.", list == null ? 0 : list.size(), time);
            }
            return list;
        } catch (DataAccessException e) {
            String details = "Sql:\n" + (logsql != null ? logsql : getFormattedSqlString(sb, 1));
            throw createServiceException(ResultCode.DB_SELECT_ERROR, details, e);
        }
    }

    @Override
    public List> queryForList(SqlBuffer sb) throws ServiceException {
        RowMapper> rowMapper = getRowToMapConverter();
        return queryForList(sb, rowMapper);
    }

    @Override
    public List> queryForList(SqlBuffer sb, RowMapper> rowMapper)
            throws ServiceException {
        VerifyTools.requireNotBlank(sb, "sqlBuffer");
        long startTime = System.currentTimeMillis();
        String logsql = null;
        if (log.isDebugEnabled()) {
            log.debug("Executing sql query:\n{}", logsql = getFormattedSqlString(sb, 1));
        }
        String sql = getPreparedSqlString(sb);
        Map params = sb.getPreparedVariables();
        try {
            List> list = namedJdbcOperations.query(sql, params, rowMapper);
            if (log.isDebugEnabled()) {
                long time = System.currentTimeMillis() - startTime;
                log.debug("Sql query returns {} rows, elapsed time {}ms.", list == null ? 0 : list.size(), time);
            }
            return list;
        } catch (DataAccessException e) {
            String details = "Sql:\n" + (logsql != null ? logsql : getFormattedSqlString(sb, 1));
            throw createServiceException(ResultCode.DB_SELECT_ERROR, details, e);
        }
    }

    @Override
    public SqlRowSet queryForRowSet(SqlBuffer sb) throws ServiceException {
        VerifyTools.requireNotBlank(sb, "sqlBuffer");
        long startTime = System.currentTimeMillis();
        String logsql = null;
        if (log.isDebugEnabled()) {
            log.debug("Executing sql query:\n{}", logsql = getFormattedSqlString(sb, 1));
        }
        String sql = getPreparedSqlString(sb);
        Map params = sb.getPreparedVariables();
        try {
            SqlRowSet result = namedJdbcOperations.queryForRowSet(sql, params);
            if (log.isDebugEnabled()) {
                long time = System.currentTimeMillis() - startTime;
                log.debug("Sql query, elapsed time {}ms.", time);
            }
            return result;
        } catch (DataAccessException e) {
            String details = "Sql:\n" + (logsql != null ? logsql : getFormattedSqlString(sb, 1));
            throw createServiceException(ResultCode.DB_SELECT_ERROR, details, e);
        }
    }

    @Override
    public int insert(SqlBuffer sb) throws ServiceException {
        VerifyTools.requireNotBlank(sb, "sqlBuffer");
        return doExecute(sb, "insert", ResultCode.DB_INSERT_ERROR);
    }

    @Override
    public int insert(SqlBuffer sb, KeyHolder generatedKeyHolder) throws ServiceException {
        VerifyTools.requireNotBlank(sb, "sqlBuffer");
        return doExecute(sb, generatedKeyHolder, "insert", ResultCode.DB_INSERT_ERROR);
    }

    @Override
    public int update(SqlBuffer sb) throws ServiceException {
        VerifyTools.requireNotBlank(sb, "sqlBuffer");
        return doExecute(sb, "update", ResultCode.DB_UPDATE_ERROR);
    }

    @Override
    public int delete(SqlBuffer sb) throws ServiceException {
        VerifyTools.requireNotBlank(sb, "sqlBuffer");
        return doExecute(sb, "delete", ResultCode.DB_DELETE_ERROR);
    }

    protected int doExecute(SqlBuffer sb, String desc, IResultMessage errorCode) throws ServiceException {
        long startTime = System.currentTimeMillis();
        String logsql = null;
        if (log.isDebugEnabled()) {
            log.debug("Executing sql {}:\n{}", desc, logsql = getFormattedSqlString(sb, 1));
        }
        String sql = getPreparedSqlString(sb);
        Map params = sb.getPreparedVariables();
        try {
            int rows = namedJdbcOperations.update(sql, params);
            if (log.isDebugEnabled()) {
                long time = System.currentTimeMillis() - startTime;
                log.debug("Sql {} affected " + rows + " rows, elapsed time {}ms", desc, time);
            }
            return rows;
        } catch (DataAccessException e) {
            String details = "Sql:\n" + (logsql != null ? logsql : getFormattedSqlString(sb, 1));
            throw createServiceException(errorCode, details, e);
        }
    }

    protected int doExecute(SqlBuffer sb, KeyHolder generatedKeyHolder, String desc, IResultMessage errorCode)
            throws ServiceException {
        long startTime = System.currentTimeMillis();
        String logsql = null;
        if (log.isDebugEnabled()) {
            log.debug("Executing sql {}:\n{}", desc, logsql = getFormattedSqlString(sb, 1));
        }
        String sql = getPreparedSqlString(sb);
        Map params = sb.getPreparedVariables();
        SqlParameterSource msps = new MapSqlParameterSource(params);
        try {
            int rows = namedJdbcOperations.update(sql, msps, generatedKeyHolder);
            if (log.isDebugEnabled()) {
                long time = System.currentTimeMillis() - startTime;
                log.debug("Sql {} affected {} rows, elapsed time {}ms", desc, rows, time);
            }
            return rows;
        } catch (DataAccessException e) {
            String details = "Sql:\n" + (logsql != null ? logsql : getFormattedSqlString(sb, 1));
            throw createServiceException(errorCode, details, e);
        }
    }

    @Override
    public int batchInsert(SqlBuffer sb) throws ServiceException {
        VerifyTools.requireNotBlank(sb, "sqlBuffer");
        return doBatchExecute(sb, "insert", ResultCode.DB_INSERT_ERROR);
    }

    @Override
    public int batchUpdate(SqlBuffer sb) throws ServiceException {
        VerifyTools.requireNotBlank(sb, "sqlBuffer");
        return doBatchExecute(sb, "update", ResultCode.DB_UPDATE_ERROR);
    }

    protected int doBatchExecute(SqlBuffer sb, String operate, IResultMessage errorCode) throws ServiceException {
        long startTime = System.currentTimeMillis();
        String logsql = null;
        if (log.isDebugEnabled()) {
            log.debug("Executing sql batch {}:\n{}", operate, logsql = getFormattedSqlString(sb, 1));
        }
        String sql = getPreparedSqlString(sb);
        Map params = sb.getPreparedVariables();
        try {
            int rows = namedJdbcOperations.update(sql, params);
            if (log.isDebugEnabled()) {
                long time = System.currentTimeMillis() - startTime;
                log.debug("Sql batch {} affected {} rows, elapsed time {}ms.", operate, rows, time);
            }
            return rows;
        } catch (DataAccessException e) {
            String details = "Sql:\n" + (logsql != null ? logsql : getFormattedSqlString(sb, 1));
            throw createServiceException(errorCode, details, e);
        }
    }

    protected String getPreparedSqlString(SqlBuffer sb) {
        String sql = sb.getPreparedSqlString();
        return plugins.replaceSql(sql, dbVersion);
    }

    protected String getFormattedSqlString(SqlBuffer sb, int indent) {
        // 未开启到TRACE级别的日志就执行省略模式
        boolean omitMode = !log.isTraceEnabled();
        String sql = sb.getLoggingSqlString(omitMode);
        return plugins.formatSql(sql, 1, dbVersion);
    }

    // key=querySql, value=countSql
    private static final Map COUNT_SQL_MAPS = new ConcurrentHashMap<>();

    @Override
    public int countByQuerySql(SqlBuffer querySql) {
        long startTime = System.currentTimeMillis();
        String namedQuerySql = getPreparedSqlString(querySql);
        String countSql;
        Object[] paramArray;
        if (COUNT_SQL_MAPS.containsKey(namedQuerySql)) {
            CountSqlItem item = COUNT_SQL_MAPS.get(namedQuerySql);
            countSql = item.countSql;
            ParsedSql parsedQuerySql = item.parsedSql;
            Map paramMaps = querySql.getPreparedVariables();
            SqlParameterSource paramSource = new MapSqlParameterSource(paramMaps);
            paramArray = NamedParameterUtils.buildValueArray(parsedQuerySql, paramSource, null);
        } else {
            // 解析查询语句生成统计语句
            Map paramMaps = querySql.getPreparedVariables();
            SqlParameterSource paramSource = new MapSqlParameterSource(paramMaps);
            ParsedSql parsedQuerySql = NamedParameterUtils.parseSqlStatement(namedQuerySql);
            String actualQuerySql = NamedParameterUtils.substituteNamedParameters(parsedQuerySql, paramSource);
            paramArray = NamedParameterUtils.buildValueArray(parsedQuerySql, paramSource, null);

            countSql = countSqlParser.getSmartCountSql(actualQuerySql);

            COUNT_SQL_MAPS.put(namedQuerySql, new CountSqlItem(parsedQuerySql, countSql));
        }

        // 输出日志
        String logsql = null;
        if (log.isDebugEnabled()) {
            log.debug("Executing sql count:\n{}", logsql = getLoggingSqlForHashParamsSql(countSql, paramArray));
        }

        long countTime = System.currentTimeMillis();
        RowMapper rowMapper = new FirstColumnMapper<>(Integer.class);
        try {
            // 执行统计语句
            JdbcOperations jdbc = namedJdbcOperations.getJdbcOperations();
            int total = jdbc.queryForObject(countSql, paramArray, rowMapper);
            if (log.isDebugEnabled()) {
                long parseMills = countTime - startTime;
                long countMills = System.currentTimeMillis() - countTime;
                log.debug("Sql count returns {}, parse time {}ms, execute time {}ms.", total, parseMills, countMills);
            }
            return total;
        } catch (DataAccessException e) {
            String details = "Sql:\n" + (logsql != null ? logsql : getLoggingSqlForHashParamsSql(countSql, paramArray));
            throw createServiceException(ResultCode.DB_SELECT_ERROR, details, e);
        }
    }

    private ServiceException createServiceException(IResultMessage resultCode, String details, DataAccessException e) {
        if (e.getCause() == null) {
            return new ServiceException(resultCode, e).setDetails(details);
        } else {
            details = StringTools.concat('\n', details, e.getCause().getMessage());
            // 异常Cause层级太深了, 而且很多重复信息, 跳过一层
            // return new ServiceException(resultCode, details, e);
            return new ServiceException(resultCode, e.getCause()).setDetails(details);
        }
    }

    private static class CountSqlItem {

        private final ParsedSql parsedSql;
        private final String countSql;

        public CountSqlItem(ParsedSql parsedSql, String countSql) {
            this.parsedSql = parsedSql;
            this.countSql = countSql;
        }
    }

    private String getLoggingSqlForHashParamsSql(String sql, Object[] params) {
        if (params == null || params.length == 0) {
            // 没有占位符
            return sql;
        } else if (StringTools.countCharacter(sql, '?') != params.length) {
            // 占位符的数量与参数个数不一致, 说明字符串中有问号, 处理起来非常麻烦, 直接输出带问题的SQL和参数
            return sql + '\n' + ConvertTools.joinToString(params, true);
        } else {
            // 根据sql和params生成SqlBuffer对象
            SqlBuffer buffer = new SqlBuffer(sqlDialect, plugins);
            int v = 0;
            for (int i = 0, z = sql.length(); i < z; i++) {
                char c = sql.charAt(i);
                if (c == '?') {
                    buffer.addVariable(params[v++]);
                } else {
                    buffer.append(c);
                }
            }
            return getFormattedSqlString(buffer, 1);
        }
    }

    @Override
    public void executeSqlScript(String sqlFilePath, Class... classes) {
        VerifyTools.requireNotBlank(sqlFilePath, "sqlFilePath");
        URL url = PathTools.findResource(sqlFilePath, classes);
        executeSqlScript(url);
    }

    @Override
    public void executeSqlScript(URL url) {
        VerifyTools.requireNotBlank(url, "url");

        JdbcOperations jdbcOperations = namedJdbcOperations.getJdbcOperations();
        if (!(jdbcOperations instanceof JdbcAccessor)) {
            throw new IllegalStateException("Unsupported JdbcOperations: " + jdbcOperations.getClass().getName());
        }
        JdbcAccessor accessor = (JdbcAccessor) jdbcOperations;
        DataSource datasource = accessor.getDataSource();
        if (datasource == null) {
            throw new IllegalStateException("Datasource is null.");
        }

        Connection connection = DataSourceUtils.getConnection(datasource);
        SqlScriptTools.executeSqlScript(connection, url, true, true, // 遇到错误继续, 忽略失败的DROP语句
            ScriptUtils.DEFAULT_COMMENT_PREFIX, // 行注释前缀: --
            ScriptUtils.DEFAULT_STATEMENT_SEPARATOR, // SQL代码块分隔符: ;
            ScriptUtils.DEFAULT_BLOCK_COMMENT_START_DELIMITER, // 块注释开始符号: /*
            ScriptUtils.DEFAULT_BLOCK_COMMENT_END_DELIMITER); // 块注释结束符号: */
    }

    @Override
    public JdbcOperations getJdbcOperations() {
        return namedJdbcOperations.getJdbcOperations();
    }

    @Override
    public NamedParameterJdbcOperations getNamedParameterJdbcOperations() {
        return namedJdbcOperations;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy