|
@@ -1,5 +1,6 @@
|
|
|
package com.elab.core.dao;
|
|
|
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
import com.elab.core.bean.PageModel;
|
|
|
import com.elab.core.dao.model.JdbcParamsModel;
|
|
|
import com.elab.core.dao.model.ListDynamicSearch;
|
|
@@ -9,6 +10,7 @@ import com.elab.core.dao.params.NamedParameterUtils2;
|
|
|
import com.elab.core.dao.params.ParsedSql2;
|
|
|
import com.elab.core.dao.row.ThirdRowMapper;
|
|
|
import com.elab.core.exception.CoreException;
|
|
|
+import com.elab.core.spring.method.BatchPreparedStatementCreator;
|
|
|
import com.elab.core.spring.method.CheckSqlProcess;
|
|
|
import com.elab.core.spring.method.DefaultCheckSQLProcess;
|
|
|
import com.elab.core.spring.method.SQLEventHandler;
|
|
@@ -23,15 +25,15 @@ import org.springframework.context.ApplicationContext;
|
|
|
import org.springframework.context.ApplicationContextAware;
|
|
|
import org.springframework.dao.DataAccessException;
|
|
|
import org.springframework.dao.EmptyResultDataAccessException;
|
|
|
-import org.springframework.jdbc.core.JdbcTemplate;
|
|
|
-import org.springframework.jdbc.core.RowMapper;
|
|
|
-import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
|
|
|
-import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
|
|
|
-import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
|
|
|
-import org.springframework.jdbc.core.namedparam.SqlParameterSource;
|
|
|
+import org.springframework.jdbc.core.*;
|
|
|
+import org.springframework.jdbc.core.namedparam.*;
|
|
|
import org.springframework.jdbc.support.GeneratedKeyHolder;
|
|
|
+import org.springframework.jdbc.support.JdbcUtils;
|
|
|
|
|
|
import javax.persistence.Column;
|
|
|
+import java.sql.PreparedStatement;
|
|
|
+import java.sql.ResultSet;
|
|
|
+import java.sql.SQLException;
|
|
|
import java.util.*;
|
|
|
|
|
|
/**
|
|
@@ -241,10 +243,12 @@ public class BasicBaseDao implements ApplicationContextAware,
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * @param sql
|
|
|
- * @param obj
|
|
|
- * @param search
|
|
|
- * @param elementType
|
|
|
+ * 查询一个集合对象并返回指定的类型
|
|
|
+ *
|
|
|
+ * @param sql SQL语句
|
|
|
+ * @param obj SQL执行参数
|
|
|
+ * @param search 查询补充的参数
|
|
|
+ * @param elementType 返回的数据类型
|
|
|
* @param <T>
|
|
|
* @return
|
|
|
* @throws Exception
|
|
@@ -252,6 +256,11 @@ public class BasicBaseDao implements ApplicationContextAware,
|
|
|
public <T> List<T> executeQueryList(String sql, Object obj, ListDynamicSearch search, Class<T> elementType) throws
|
|
|
Exception {
|
|
|
JdbcParamsModel jdbcParamsModel = commonParseSql(sql, obj, search);
|
|
|
+ List<T> ts = findForList(elementType, jdbcParamsModel);
|
|
|
+ return ts;
|
|
|
+ }
|
|
|
+
|
|
|
+ private <T> List<T> findForList(Class<T> elementType, JdbcParamsModel jdbcParamsModel) {
|
|
|
long start = System.currentTimeMillis();
|
|
|
List<T> ts = (List<T>) this.jdbcTemplate.query(jdbcParamsModel.getSql(), jdbcParamsModel.getObjects(), new TimeRowMapperResultSetExtractor(new ThirdRowMapper<T>(elementType)));
|
|
|
long time = System.currentTimeMillis() - start;
|
|
@@ -316,8 +325,8 @@ public class BasicBaseDao implements ApplicationContextAware,
|
|
|
* @param o 参数
|
|
|
* @return
|
|
|
*/
|
|
|
- public List<Map<String, Object>> executeQueryForListMap(String sql, Object o) throws Exception {
|
|
|
- JdbcParamsModel jdbcParamsModel = commonParseSql(sql, o);
|
|
|
+ public List<Map<String, Object>> executeQueryForListMap(String sql, Object o, ListDynamicSearch dynamicSearch) throws Exception {
|
|
|
+ JdbcParamsModel jdbcParamsModel = commonParseSql(sql, o, dynamicSearch);
|
|
|
long start = System.currentTimeMillis();
|
|
|
List<Map<String, Object>> maps = this.jdbcTemplate.queryForList(jdbcParamsModel.getSql(), jdbcParamsModel.getObjects());
|
|
|
long time = System.currentTimeMillis() - start;
|
|
@@ -461,6 +470,9 @@ public class BasicBaseDao implements ApplicationContextAware,
|
|
|
return map;
|
|
|
}
|
|
|
|
|
|
+ public int insert(String sql, Object o) throws Exception {
|
|
|
+ return insert("", "", sql, o);
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
* 添加数据操作
|
|
@@ -469,18 +481,22 @@ public class BasicBaseDao implements ApplicationContextAware,
|
|
|
* @param o 参数对象
|
|
|
* @return
|
|
|
*/
|
|
|
- public int insert(String sql, Object o) {
|
|
|
+ public int insert(String sqlId, String table, String sql, Object o) throws Exception {
|
|
|
+ int result = 0;
|
|
|
SqlParameterSource sqlParameterSource = getSqlParameterSource(o);
|
|
|
GeneratedKeyHolder keyHolder = new GeneratedKeyHolder();
|
|
|
- sqlInvokeBefore(SqlCommandType.INSERT, sql, o);
|
|
|
+ sqlInvokeBefore(SqlCommandType.INSERT, sqlId, table, sql, o);
|
|
|
long start = System.currentTimeMillis();
|
|
|
- logger.debug("sql : " + sql);
|
|
|
+ logger.debug("sql : " + sql + "\r\n" + JSON.toJSONString(o));
|
|
|
this.getNamedParameterJdbcTemplate().update(sql, sqlParameterSource, keyHolder);
|
|
|
- int result = keyHolder.getKey().intValue();
|
|
|
- logger.debug(" params : " + result);
|
|
|
+ // 如果存在自动生成的主键,不存在那么表示参数中已经涵盖了,不需要返回。
|
|
|
+ if (keyHolder.getKey() != null) {
|
|
|
+ result = keyHolder.getKey().intValue();
|
|
|
+ }
|
|
|
+ logger.debug(" 得到主键 : " + result);
|
|
|
long time = System.currentTimeMillis() - start;
|
|
|
logger.debug(" SQL 执行耗时 : " + time);
|
|
|
- sqlInvokeAfter(SqlCommandType.INSERT, sql, o, result);
|
|
|
+ sqlInvokeAfter(SqlCommandType.INSERT, sqlId, table, sql, o, result);
|
|
|
return result;
|
|
|
}
|
|
|
|
|
@@ -503,14 +519,21 @@ public class BasicBaseDao implements ApplicationContextAware,
|
|
|
return sqlParameterSource;
|
|
|
}
|
|
|
|
|
|
+ public int[] batchOperation(SqlCommandType sqlCommandType, String sql, List list)
|
|
|
+ throws Exception {
|
|
|
+ return batchOperation(sqlCommandType, "", "", sql, list);
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 批量操作
|
|
|
*
|
|
|
- * @param sql sql语句
|
|
|
- * @param list 数据集合
|
|
|
+ * @param sqlCommandType 执行的SQL命令类型
|
|
|
+ * @param sql sql语句
|
|
|
+ * @param list 数据集合
|
|
|
* @return
|
|
|
*/
|
|
|
- public int[] batchOperation(String sql, List list) throws Exception {
|
|
|
+ public int[] batchOperation(SqlCommandType sqlCommandType, String sqlId, String table, String sql, List list) throws
|
|
|
+ Exception {
|
|
|
if (list != null && list.size() > 0) {
|
|
|
long start = System.currentTimeMillis();
|
|
|
logger.debug("sql : " + sql);
|
|
@@ -529,7 +552,16 @@ public class BasicBaseDao implements ApplicationContextAware,
|
|
|
SqlParameterSource sqlParameterSource = getConvertSqlParameterSource(bean, nameMap);
|
|
|
parameterSource[i] = sqlParameterSource;
|
|
|
}
|
|
|
- int[] results = this.getNamedParameterJdbcTemplate().batchUpdate(sql, parameterSource);
|
|
|
+
|
|
|
+ int[] results;
|
|
|
+ sqlInvokeBefore(sqlCommandType, sqlId, table, sql, list);
|
|
|
+ // 如果是批量新增的情况,则要将新增的批量编号进行返回
|
|
|
+ if (SqlCommandType.INSERT == sqlCommandType) {
|
|
|
+ results = batchInsert(sql, parameterSource);
|
|
|
+ } else {
|
|
|
+ results = this.getNamedParameterJdbcTemplate().batchUpdate(sql, parameterSource);
|
|
|
+ }
|
|
|
+ sqlInvokeAfter(sqlCommandType, sqlId, table, sql, list, results);
|
|
|
logger.debug(" params size : " + list.size());
|
|
|
long time = System.currentTimeMillis() - start;
|
|
|
logger.debug(" SQL 执行耗时 : " + time);
|
|
@@ -539,24 +571,126 @@ public class BasicBaseDao implements ApplicationContextAware,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private void sqlInvokeBefore(SqlCommandType event, String sql, Object o) {
|
|
|
+ /**
|
|
|
+ * 批量返回新增结果
|
|
|
+ *
|
|
|
+ * @param sql 要执行的SQL
|
|
|
+ * @param parameterSource 参数对象
|
|
|
+ * @return
|
|
|
+ * @throws SQLException
|
|
|
+ */
|
|
|
+ private int[] batchInsert(String sql, SqlParameterSource[] parameterSource) throws SQLException {
|
|
|
+ ParsedSql parsedSql = NamedParameterUtils.parseSqlStatement(sql);
|
|
|
+ String sqlToUse = NamedParameterUtils.substituteNamedParameters(parsedSql, parameterSource[0]);
|
|
|
+ List<SqlParameter> declaredParameters = NamedParameterUtils.buildSqlParameterList(parsedSql, parameterSource[0]);
|
|
|
+ PreparedStatementCreatorFactory pscf = new PreparedStatementCreatorFactory(sqlToUse, declaredParameters);
|
|
|
+ /**
|
|
|
+ * 参数执行处理
|
|
|
+ */
|
|
|
+ BatchPreparedStatementSetter pss = new BatchPreparedStatementSetter() {
|
|
|
+ @Override
|
|
|
+ public void setValues(PreparedStatement ps, int i) throws SQLException {
|
|
|
+ // 将SQL的中的:参数转化成数组
|
|
|
+ Object[] values = NamedParameterUtils.buildValueArray(parsedSql, parameterSource[i], null);
|
|
|
+ // 转化成数组之后一个个和?对应填充
|
|
|
+ pscf.newPreparedStatementSetter(values).setValues(ps);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public int getBatchSize() {
|
|
|
+ return parameterSource.length;
|
|
|
+ }
|
|
|
+ };
|
|
|
+ /**
|
|
|
+ * 创建Statement对象的时候,加上Statement.RETURN_GENERATED_KEYS参数
|
|
|
+ */
|
|
|
+ BatchPreparedStatementCreator batchPreparedStatementCreator = new BatchPreparedStatementCreator(sqlToUse);
|
|
|
+ return jdbcTemplate.execute(batchPreparedStatementCreator, (PreparedStatementCallback<int[]>) ps -> {
|
|
|
+ try {
|
|
|
+ int batchSize = pss.getBatchSize();
|
|
|
+ int[] keys = new int[batchSize];
|
|
|
+
|
|
|
+ InterruptibleBatchPreparedStatementSetter ipss =
|
|
|
+ (pss instanceof InterruptibleBatchPreparedStatementSetter ?
|
|
|
+ (InterruptibleBatchPreparedStatementSetter) pss : null);
|
|
|
+ if (JdbcUtils.supportsBatchUpdates(ps.getConnection())) {
|
|
|
+ for (int i = 0; i < batchSize; i++) {
|
|
|
+ pss.setValues(ps, i);
|
|
|
+ if (ipss != null && ipss.isBatchExhausted(i)) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ ps.addBatch();
|
|
|
+ }
|
|
|
+ ps.executeBatch();
|
|
|
+ // 将插入的主键值返回出来
|
|
|
+ ResultSet rs = ps.getGeneratedKeys();
|
|
|
+ int index = 0;
|
|
|
+ while (rs.next() && index < batchSize) {
|
|
|
+ keys[index] = rs.getInt(1);
|
|
|
+ index++;
|
|
|
+ }
|
|
|
+ return keys;
|
|
|
+ } else {
|
|
|
+ List<Integer> rowsAffected = new ArrayList<>();
|
|
|
+ for (int i = 0; i < batchSize; i++) {
|
|
|
+ pss.setValues(ps, i);
|
|
|
+ if (ipss != null && ipss.isBatchExhausted(i)) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ rowsAffected.add(ps.executeUpdate());
|
|
|
+ }
|
|
|
+ int[] rowsAffectedArray = new int[rowsAffected.size()];
|
|
|
+ for (int i = 0; i < rowsAffectedArray.length; i++) {
|
|
|
+ rowsAffectedArray[i] = rowsAffected.get(i);
|
|
|
+ }
|
|
|
+ return rowsAffectedArray;
|
|
|
+ }
|
|
|
+ } finally {
|
|
|
+ if (pss instanceof ParameterDisposer) {
|
|
|
+ ((ParameterDisposer) pss).cleanupParameters();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ protected PreparedStatementCreatorFactory getPreparedStatementCreatorFactory(
|
|
|
+ ParsedSql parsedSql, SqlParameterSource paramSource) {
|
|
|
+ String sqlToUse = NamedParameterUtils.substituteNamedParameters(parsedSql, paramSource);
|
|
|
+ List<SqlParameter> declaredParameters = NamedParameterUtils.buildSqlParameterList(parsedSql, paramSource);
|
|
|
+ return new PreparedStatementCreatorFactory(sqlToUse, declaredParameters);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void sqlInvokeBefore(SqlCommandType event, String sqlId, String table, String sql, Object o) {
|
|
|
if (this.sqlEventHandlerList != null && this.sqlEventHandlerList.size() > 0) {
|
|
|
for (int i = 0; i < sqlEventHandlerList.size(); i++) {
|
|
|
SQLEventHandler sqlEventHandler = sqlEventHandlerList.get(i);
|
|
|
- sqlEventHandler.sqlInvokeBefore(event, sql, o);
|
|
|
+ sqlEventHandler.sqlInvokeBefore(event, sqlId, table, sql, o);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private void sqlInvokeAfter(SqlCommandType event, String sql, Object request, Object result) {
|
|
|
+ private void sqlInvokeAfter(SqlCommandType event, String sqlId, String table, String sql, Object request, Object
|
|
|
+ result) {
|
|
|
if (this.sqlEventHandlerList != null && this.sqlEventHandlerList.size() > 0) {
|
|
|
for (int i = 0; i < sqlEventHandlerList.size(); i++) {
|
|
|
SQLEventHandler sqlEventHandler = sqlEventHandlerList.get(i);
|
|
|
- sqlEventHandler.sqlInvokeAfter(event, sql, request, result);
|
|
|
+ sqlEventHandler.sqlInvokeAfter(event, sqlId, table, sql, request, result);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 执行修改
|
|
|
+ *
|
|
|
+ * @param sql
|
|
|
+ * @param o
|
|
|
+ * @return
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ public int update(String sql, Object o) throws Exception {
|
|
|
+ return update("", "", sql, o);
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 修改数据操作
|
|
|
*
|
|
@@ -564,13 +698,13 @@ public class BasicBaseDao implements ApplicationContextAware,
|
|
|
* @param o 对象
|
|
|
* @return
|
|
|
*/
|
|
|
- public int update(String sql, Object o) throws Exception {
|
|
|
+ public int update(String sqlId, String table, String sql, Object o) throws Exception {
|
|
|
JdbcParamsModel jdbcParamsModel = commonParseSql(sql, o);
|
|
|
- sqlInvokeBefore(SqlCommandType.UPDATE, sql, o);
|
|
|
+ sqlInvokeBefore(SqlCommandType.UPDATE, sqlId, table, sql, o);
|
|
|
long start = System.currentTimeMillis();
|
|
|
int update = this.jdbcTemplate.update(jdbcParamsModel.getSql(), jdbcParamsModel.getObjects());
|
|
|
long time = System.currentTimeMillis() - start;
|
|
|
- sqlInvokeAfter(SqlCommandType.UPDATE, sql, o, update);
|
|
|
+ sqlInvokeAfter(SqlCommandType.UPDATE, sqlId, table, sql, o, update);
|
|
|
logger.debug(" SQL 执行耗时 : " + time);
|
|
|
return update;
|
|
|
}
|