package com.yanzuoguang.db.impl; import com.yanzuoguang.db.ConfigDb; import com.yanzuoguang.db.DbExecute; import com.yanzuoguang.log.AspectLogResult; import com.yanzuoguang.log.AspectLogStart; import com.yanzuoguang.log.LogInfoVo; import com.yanzuoguang.util.vo.MapRow; import com.yanzuoguang.util.vo.Ref; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowCallbackHandler; import org.springframework.jdbc.support.rowset.SqlRowSet; import org.springframework.stereotype.Component; import java.util.List; /** * 数据库操作类 * * @author 颜佐光 */ @Component public class DbExecuteImpl implements DbExecute { private final JdbcTemplate jdbcTemplate; private final DbExecutePrintSql printSql; private final ConfigDb configDb; private final AspectLogStart aspectLogStart; private final AspectLogResult aspectLogResult; public DbExecuteImpl(JdbcTemplate jdbcTemplate, DbExecutePrintSql printSql, ConfigDb configDb, AspectLogStart aspectLogStart, AspectLogResult aspectLogResult) { this.jdbcTemplate = jdbcTemplate; this.printSql = printSql; this.configDb = configDb; this.aspectLogStart = aspectLogStart; this.aspectLogResult = aspectLogResult; } public JdbcTemplate getJdbc() { return jdbcTemplate; } /** * 更新SQL语句的执行 * * @param targetClass 触发类 * @param sqlName SQL语句名称 * @param sql SQL语句 * @param paras 参数信息 * @return 影响行数 */ @Override public int update(Class<?> targetClass, String sqlName, String sql, Object... paras) { SqlInfo sqlInfo = new SqlInfo(targetClass, sqlName, sql, paras); Ref<Integer> ret = new Ref<>(0); executeSql(sqlInfo, (row, start) -> row.value = ret.value = getJdbc().update(sqlInfo.getSql(), sqlInfo.getParas()) ); return ret.value; } /** * 查询数据 * * @param targetClass 触发类 * @param sqlName SQL语句名称 * @param cls 查询的结果的类型 * @param rowHandle 通过该类来处理结果 * @param sql 需要查询的SQL语句 * @param paras 查询语句的参数 * @param <T> 返回的集合的类型 */ @Override public <T> void query(Class<?> targetClass, Class<T> cls, DbRow<T> rowHandle, String sqlName, String sql, Object... paras) { SqlInfo sqlInfo = new SqlInfo(targetClass, sqlName, sql, paras); executeSql(sqlInfo, (row, start) -> { RowCallbackHandler rowCallbackHandler = rs -> { AllBeanRowMapper<T> rowMap = AllBeanRowMapper.getInstance(cls, configDb); T data = rowMap.mapRow(rs, row.value); rowHandle.handle(data); row.value++; }; this.getJdbc().query(sqlInfo.getSql(), rowCallbackHandler, sqlInfo.getParas()); }); } /** * 查询数据,并返回集合 * * @param targetClass 触发类 * @param sqlName SQL语句名称 * @param cls 查询的结果的类型 * @param sql 需要查询的SQL语句 * @param paras 查询语句的参数 * @param <T> 返回的集合的类型 * @return 集合 */ @Override public <T> List<T> query(Class<?> targetClass, Class<T> cls, String sqlName, String sql, Object... paras) { SqlInfo sqlInfo = new SqlInfo(targetClass, sqlName, sql, paras); Ref<List<T>> ret = new Ref<>(null); executeSql(sqlInfo, (row, start) -> { ret.value = this.getJdbc().query(sqlInfo.getSql(), sqlInfo.getParas(), AllBeanRowMapper.getInstance(cls, configDb)); row.value = ret.value.size(); }); return ret.value; } /** * 查询数据,并返回集合 * * @param targetClass 触发类 * @param sqlName SQL语句名称 * @param sql 需要查询的SQL语句 * @param paras 查询语句的参数 * @return 集合 */ @Override public List<MapRow> query(Class<?> targetClass, String sqlName, String sql, Object... paras) { return query(targetClass, MapRow.class, sqlName, sql, paras); } /** * 查询第一个单元格的信息 * * @param targetClass 触发类 * @param sqlName SQL语句名称 * @param sql SQL语句 * @param paras 参数信息 * @return 第一个单元格的数据 */ @Override public Object queryCell(Class<?> targetClass, String sqlName, String sql, Object... paras) { SqlInfo sqlInfo = new SqlInfo(targetClass, sqlName, sql, paras); Ref<Object> ret = new Ref<>(null); executeSql(sqlInfo, (row, start) -> { SqlRowSet rowSet = getJdbc().queryForRowSet(sqlInfo.getSql(), sqlInfo.getParas()); if (rowSet.next()) { row.value = 1; ret.value = rowSet.getObject(1); } }); return ret.value; } /** * 执行sql语句 * * @param sqlInfo sql语句信息 * @param sqlFunction 执行函数,传入参数为影响的行数引用和开始执行时间 */ private void executeSql(SqlInfo sqlInfo, DbSqlFunction<Ref<Integer>, Long> sqlFunction) { // 开始记录日志 LogInfoVo log = aspectLogStart.requestLog(sqlInfo.getTargetClass(), "Sql", String.format("%s:%s", sqlInfo.getTargetClass().getSimpleName(), sqlInfo.getSqlName()), sqlInfo, true); // 开始时间 long start = System.currentTimeMillis(); Ref<Integer> row = new Ref<>(0); sqlInfo.setSql(this.handleParas(sqlInfo.getSql())); try { // 执行得函数 sqlFunction.accept(row, start); // 写入日志 aspectLogResult.responseLog(log, row, null); } catch (Exception ex) { // 写入日志 aspectLogResult.responseLog(log, row, ex); throw ex; } finally { // 打印sql语句 printSql.print(sqlInfo, log.getUseTime(), row.value); } } /** * 处理SQL语句和参数值 * * @param sql 处理sql语句 * @return 可执行的sql语句 */ protected String handleParas(String sql) { return sql.replaceAll("1\\s*?=\\s*?1\\s*?(?i)AND", "") .replaceAll("(?i)WHERE\\s*?1\\s*?=\\s*?1", "") .replaceAll("((?i)ORDER\\s*?(?i)BY\\s*?)1\\s*?,", "$1") .replaceAll("(?i)ORDER\\s*?(?i)BY\\s*?1\\s*?", "") .replaceAll("((?i)GROUP\\s*?(?i)BY\\s*?)1\\s*?,", "$1") .replaceAll("(?i)GROUP\\s*?(?i)BY\\s*?1\\s*?", ""); } }