|
|
@@ -0,0 +1,1948 @@
|
|
|
+package com.kym.jdbc.template;
|
|
|
+
|
|
|
+import com.kym.DbUtil;
|
|
|
+import com.kym.JacksonUtil;
|
|
|
+import com.kym.jdbc.BasicQuery;
|
|
|
+import com.kym.jdbc.Bean;
|
|
|
+import com.kym.jdbc.IHandler;
|
|
|
+import com.kym.jdbc.OBuilder;
|
|
|
+import com.kym.jdbc.ResultHandler;
|
|
|
+import com.kym.jdbc.SQLEntity;
|
|
|
+import com.kym.jdbc.annotations.DBF;
|
|
|
+import com.kym.jdbc.annotations.Entity;
|
|
|
+import com.kym.jdbc.annotations.Many;
|
|
|
+import com.kym.jdbc.annotations.One;
|
|
|
+import com.kym.jdbc.annotations.QE;
|
|
|
+import com.kym.jdbc.lambda.ColumnFunc;
|
|
|
+import com.kym.jdbc.lambda.DefaultLambdaParser;
|
|
|
+import org.slf4j.Logger;
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
+import org.springframework.dao.DataAccessException;
|
|
|
+import org.springframework.jdbc.core.BatchPreparedStatementSetter;
|
|
|
+import org.springframework.jdbc.core.CallableStatementCallback;
|
|
|
+import org.springframework.jdbc.core.CallableStatementCreator;
|
|
|
+import org.springframework.jdbc.core.JdbcTemplate;
|
|
|
+import org.springframework.jdbc.core.PreparedStatementCreator;
|
|
|
+import org.springframework.jdbc.core.ResultSetExtractor;
|
|
|
+import org.springframework.jdbc.core.RowMapper;
|
|
|
+import org.springframework.jdbc.support.GeneratedKeyHolder;
|
|
|
+import org.springframework.jdbc.support.KeyHolder;
|
|
|
+
|
|
|
+import java.lang.reflect.Field;
|
|
|
+import java.lang.reflect.Modifier;
|
|
|
+import java.lang.reflect.ParameterizedType;
|
|
|
+import java.lang.reflect.Type;
|
|
|
+import java.math.BigDecimal;
|
|
|
+import java.sql.CallableStatement;
|
|
|
+import java.sql.Connection;
|
|
|
+import java.sql.PreparedStatement;
|
|
|
+import java.sql.ResultSet;
|
|
|
+import java.sql.ResultSetMetaData;
|
|
|
+import java.sql.SQLException;
|
|
|
+import java.sql.Types;
|
|
|
+import java.time.LocalDate;
|
|
|
+import java.time.LocalDateTime;
|
|
|
+import java.time.LocalTime;
|
|
|
+import java.time.ZoneId;
|
|
|
+import java.time.format.DateTimeFormatter;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.Arrays;
|
|
|
+import java.util.Collection;
|
|
|
+import java.util.Collections;
|
|
|
+import java.util.Date;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.HashSet;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.Optional;
|
|
|
+import java.util.Set;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+
|
|
|
+/**
|
|
|
+ * sql处理封装(jdbcTemplate版本)
|
|
|
+ *
|
|
|
+ * @author yaop
|
|
|
+ */
|
|
|
+public class JdbcExecute implements IHandler {
|
|
|
+ private final Logger logger = LoggerFactory.getLogger(JdbcExecute.class);
|
|
|
+
|
|
|
+ private List<String> ignores;
|
|
|
+
|
|
|
+ private JdbcTemplate jdbcTemplate;
|
|
|
+
|
|
|
+ private JdbcHelper helper;
|
|
|
+
|
|
|
+ public static final int FUNC_SUM = 1;
|
|
|
+ public static final int FUNC_AVG = 2;
|
|
|
+ public static final int FUNC_MIN = 3;
|
|
|
+ public static final int FUNC_MAX = 4;
|
|
|
+ public static final int FUNC_COUNT = 5;
|
|
|
+
|
|
|
+ public void setJdbcTemplate(JdbcTemplate jdbcTemplate, int dialect) {
|
|
|
+ this.jdbcTemplate = jdbcTemplate;
|
|
|
+ helper = new JdbcHelper();
|
|
|
+ helper.setDialect(dialect);
|
|
|
+ ignores = new ArrayList<>();
|
|
|
+ ignores.add("richId");
|
|
|
+ ignores.add("rich1Id");
|
|
|
+ ignores.add("rich2Id");
|
|
|
+ }
|
|
|
+
|
|
|
+ public int getJdbcDialect() {
|
|
|
+ return helper.getDialect();
|
|
|
+ }
|
|
|
+
|
|
|
+ protected void beforeInsert(Object bean) {
|
|
|
+ if (null == bean) {
|
|
|
+ throw new IllegalStateException("no bean to insert into db");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ protected void beforeUpdate(Object bean) {
|
|
|
+ if (null == bean) {
|
|
|
+ throw new IllegalStateException("no bean update to db");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ protected void beforeUpdate(Object bean, OBuilder OBuilder) {
|
|
|
+ if (null == bean) {
|
|
|
+ throw new IllegalStateException("no bean update to db");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ protected void beforeDelete(Class<?> clz, OBuilder OBuilder) {
|
|
|
+ if (null == clz) {
|
|
|
+ throw new IllegalStateException("no bean to delete from db");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ protected void beforeDelete(Class<?> clz, Object id) {
|
|
|
+ if (null == clz) {
|
|
|
+ throw new IllegalStateException("no bean to delete from db");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ protected void beforeSelect(BasicQuery query) {
|
|
|
+ if (null == query) {
|
|
|
+ throw new IllegalStateException("no bean to query from db");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ protected void beforeSelect(Class<?> clz, OBuilder OBuilder) {
|
|
|
+ if (null == clz) {
|
|
|
+ throw new IllegalStateException("no bean to query from db");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private List<String> addExcludeInSelectList(Class<?> clz, String... excludes) {
|
|
|
+ List<String> exclude = new ArrayList<>();
|
|
|
+ if (!DbUtil.isEmptyOrNull(excludes)) {
|
|
|
+ exclude.addAll(Arrays.asList(excludes));
|
|
|
+ }
|
|
|
+ Field[] fields = clz.getFields();
|
|
|
+ for (Field field : fields) {
|
|
|
+ String fieldName = field.getName();
|
|
|
+ Type type = field.getGenericType();
|
|
|
+ if (type == List.class || type == Set.class) {
|
|
|
+ exclude.add(fieldName);
|
|
|
+ }
|
|
|
+ if (ignores.contains(fieldName)) {
|
|
|
+ exclude.add(fieldName);
|
|
|
+ exclude.add(fieldName.replace("Id", "Content"));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return exclude;
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<String> addExcludeInSelectList(BasicQuery query, String... excludes) {
|
|
|
+ List<String> exclude = new ArrayList<>();
|
|
|
+ if (!DbUtil.isEmptyOrNull(excludes)) {
|
|
|
+ exclude.addAll(Arrays.asList(excludes));
|
|
|
+ }
|
|
|
+
|
|
|
+ Field[] fields = query.getClass().getAnnotation(QE.class).clz().getFields();
|
|
|
+ for (Field field : fields) {
|
|
|
+ String fieldName = field.getName();
|
|
|
+ Type type = field.getGenericType();
|
|
|
+ if (type == List.class || type == Set.class) {
|
|
|
+ exclude.add(fieldName);
|
|
|
+ }
|
|
|
+ if (ignores.contains(fieldName)) {
|
|
|
+ exclude.add(fieldName);
|
|
|
+ exclude.add(fieldName.replace("Id", "Content"));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return exclude;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ //region select
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 分页查询
|
|
|
+ */
|
|
|
+ public final Map<String, Object> selectPageList(BasicQuery query) {
|
|
|
+ beforeSelect(query);
|
|
|
+ Map<String, Object> map = new HashMap<>(2);
|
|
|
+ int pageSize = query.pageSize;
|
|
|
+ long count = selectCount(query);
|
|
|
+ if (0 == count) {
|
|
|
+ map.put("list", Collections.emptyList());
|
|
|
+ } else {
|
|
|
+ query.pageSize = pageSize;
|
|
|
+ map.put("list", selectList(query));
|
|
|
+ }
|
|
|
+ map.put("count", count);
|
|
|
+ return map;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 分页查询
|
|
|
+ */
|
|
|
+ public final Map<String, Object> selectPageList(Class<?> clz, OBuilder OBuilder) {
|
|
|
+ beforeSelect(clz, OBuilder);
|
|
|
+ Map<String, Object> map = new HashMap<>(2);
|
|
|
+ long count = selectCount(clz, OBuilder);
|
|
|
+ if (0 == count) {
|
|
|
+ map.put("list", Collections.emptyList());
|
|
|
+ } else {
|
|
|
+ map.put("list", selectList(clz, OBuilder));
|
|
|
+ }
|
|
|
+ map.put("count", count);
|
|
|
+ return map;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 分页查询
|
|
|
+ */
|
|
|
+ public final <T> Bean<T> selectPageBean(BasicQuery query) {
|
|
|
+ Bean<T> pageBean = new Bean<>();
|
|
|
+ pageBean.pageIndex = query.pageIndex;
|
|
|
+ pageBean.pageSize = query.pageSize;
|
|
|
+ beforeSelect(query);
|
|
|
+ long count = selectCount(query);
|
|
|
+ pageBean.count = count;
|
|
|
+ if (0 == count) {
|
|
|
+ pageBean.list = Collections.emptyList();
|
|
|
+ } else {
|
|
|
+ query.pageSize = pageBean.pageSize;
|
|
|
+ pageBean.list = selectList(query);
|
|
|
+ }
|
|
|
+ return pageBean;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 分页查询
|
|
|
+ */
|
|
|
+ public final <T> Bean<T> selectPageBean(Class<T> clz, OBuilder OBuilder) {
|
|
|
+ Bean<T> pageBean = new Bean<>();
|
|
|
+ beforeSelect(clz, OBuilder);
|
|
|
+ long count = selectCount(clz, OBuilder);
|
|
|
+ pageBean.count = count;
|
|
|
+ pageBean.pageIndex = OBuilder.limitStart();
|
|
|
+ pageBean.pageSize = OBuilder.limitDelta();
|
|
|
+ if (0 == count) {
|
|
|
+ pageBean.list = Collections.emptyList();
|
|
|
+ } else {
|
|
|
+ pageBean.list = selectList(clz, OBuilder);
|
|
|
+ }
|
|
|
+ return pageBean;
|
|
|
+ }
|
|
|
+
|
|
|
+ public final <T> List<T> selectListExclude(Class<T> clz, String... exclude) {
|
|
|
+ return selectListExclude(clz, OBuilder.build(), exclude);
|
|
|
+ }
|
|
|
+
|
|
|
+ public final <T> List<T> selectList(Class<T> clz, String... include) {
|
|
|
+ return selectList(clz, OBuilder.build(), include);
|
|
|
+ }
|
|
|
+
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
+ public final <T> List<T> selectListExclude(BasicQuery query, String... exclude) {
|
|
|
+ beforeSelect(query);
|
|
|
+ SQLEntity entity = helper.selectListByQuery(query, null, addExcludeInSelectList(query, exclude));
|
|
|
+ Class<T> clz = (Class<T>) query.getClass().getAnnotation(QE.class).clz();
|
|
|
+ return queryForList(entity, clz);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 查询列表数据<p>
|
|
|
+ * <b>注意:query查询默认分页20</b></p>
|
|
|
+ */
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
+ public final <T> List<T> selectList(BasicQuery query, String... include) {
|
|
|
+ beforeSelect(query);
|
|
|
+ SQLEntity entity = helper.selectListByQuery(query, new ArrayList<>(Arrays.asList(include)), addExcludeInSelectList(query));
|
|
|
+ Class<T> clz = (Class<T>) query.getClass().getAnnotation(QE.class).clz();
|
|
|
+ return queryForList(entity, clz);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * TODO 简单查询不做关联
|
|
|
+ */
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
+ public final <T> List<T> selectList(BasicQuery query, boolean simple, String... include) {
|
|
|
+ beforeSelect(query);
|
|
|
+ SQLEntity entity = helper.selectListByQuery(query, new ArrayList<>(Arrays.asList(include)), addExcludeInSelectList(query));
|
|
|
+ Class<T> clz = (Class<T>) query.getClass().getAnnotation(QE.class).clz();
|
|
|
+ return queryForList(entity, clz);
|
|
|
+ }
|
|
|
+
|
|
|
+ private <T> List<T> queryForList(SQLEntity entity, Class<T> clz) {
|
|
|
+ long start = System.currentTimeMillis();
|
|
|
+ if (logger.isInfoEnabled()) {
|
|
|
+ logger.info("SQL>>>:\n{} \nP:{}", entity.sql, JacksonUtil.toJSONString(entity.parameters));
|
|
|
+ }
|
|
|
+ List<T> result = jdbcTemplate.query(connection -> {
|
|
|
+ PreparedStatement ps = connection.prepareStatement(entity.sql);
|
|
|
+ DbUtil.setParameter(ps, entity.parameters);
|
|
|
+ return ps;
|
|
|
+ }, (rs, i) -> map2Object(clz, rs));
|
|
|
+
|
|
|
+
|
|
|
+ if (logger.isDebugEnabled()) {
|
|
|
+ logger.info("SQL<<< cost:{}ms", System.currentTimeMillis() - start);
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public final <T> List<T> selectListExclude(Class<T> clz, OBuilder oBuilder, String... exclude) {
|
|
|
+ beforeSelect(clz, oBuilder);
|
|
|
+ SQLEntity entity = helper.selectListByWhere(clz, oBuilder, null, addExcludeInSelectList(clz, exclude), true);
|
|
|
+ return queryForList(entity, clz);
|
|
|
+ }
|
|
|
+
|
|
|
+ public final <T> List<T> selectList(Class<T> clz, OBuilder oBuilder, String... include) {
|
|
|
+ beforeSelect(clz, oBuilder);
|
|
|
+ SQLEntity entity = helper.selectListByWhere(clz, oBuilder, new ArrayList<>(Arrays.asList(include)), addExcludeInSelectList(clz), true);
|
|
|
+ return queryForList(entity, clz);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public final <T> List<T> selectSimpleList(Class<T> clz, OBuilder oBuilder) {
|
|
|
+ beforeSelect(clz, oBuilder);
|
|
|
+ List<String> includes = new ArrayList<>();
|
|
|
+ includes.add("id");
|
|
|
+ includes.add("name");
|
|
|
+ SQLEntity entity = helper.selectListByWhere(clz, oBuilder, includes, addExcludeInSelectList(clz), true);
|
|
|
+ return queryForList(entity, clz);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * jdbc查询
|
|
|
+ *
|
|
|
+ * @param sql
|
|
|
+ * @param parameters
|
|
|
+ * @return 未封装的列表
|
|
|
+ */
|
|
|
+ public final List<Map<String, Object>> selectListForMap(String sql, Object... parameters) {
|
|
|
+ long start = System.currentTimeMillis();
|
|
|
+ if (logger.isInfoEnabled()) {
|
|
|
+ logger.info("SQL>>>:\n{} \nP:{}", sql, JacksonUtil.toJSONString(parameters));
|
|
|
+ }
|
|
|
+ List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql, parameters);
|
|
|
+
|
|
|
+ if (logger.isDebugEnabled()) {
|
|
|
+ logger.info("SQL<<< cost:{}ms", System.currentTimeMillis() - start);
|
|
|
+ }
|
|
|
+ return maps;
|
|
|
+ }
|
|
|
+
|
|
|
+ public final List<Map<String, Object>> selectListForMapV2(String sql, Object... parameters) {
|
|
|
+// List<Map<String, Object>> result = new ArrayList<>();
|
|
|
+ long start = System.currentTimeMillis();
|
|
|
+ if (logger.isInfoEnabled()) {
|
|
|
+ logger.info("SQL>>>:\n{} \nP:{}", sql, JacksonUtil.toJSONString(parameters));
|
|
|
+ }
|
|
|
+ List<Map<String, Object>> result = jdbcTemplate.query(new PreparedStatementCreator() {
|
|
|
+ @Override
|
|
|
+ public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
|
|
|
+ PreparedStatement preparedStatement = connection.prepareStatement(sql);
|
|
|
+ DbUtil.setParameter(preparedStatement, parameters);
|
|
|
+ return preparedStatement;
|
|
|
+ }
|
|
|
+ }, new RowMapper<Map<String, Object>>() {
|
|
|
+ @Override
|
|
|
+ public Map<String, Object> mapRow(ResultSet rs, int i) throws SQLException {
|
|
|
+ return resultToOneMap(rs);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ if (logger.isDebugEnabled()) {
|
|
|
+ logger.info("SQL<<< cost:{}ms", System.currentTimeMillis() - start);
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public final <T> List<T> selectList(String sql, ResultHandler<T> handler, Object... parameters) {
|
|
|
+ long start = System.currentTimeMillis();
|
|
|
+ if (logger.isInfoEnabled()) {
|
|
|
+ logger.info("selectList 11 SQL>>>:\n{} \nP:{}", sql, JacksonUtil.toJSONString(parameters));
|
|
|
+ }
|
|
|
+ List<T> result = jdbcTemplate.query(new PreparedStatementCreator() {
|
|
|
+ @Override
|
|
|
+ public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
|
|
|
+ PreparedStatement preparedStatement = connection.prepareStatement(sql);
|
|
|
+ DbUtil.setParameter(preparedStatement, parameters);
|
|
|
+ return preparedStatement;
|
|
|
+ }
|
|
|
+ }, new RowMapper<T>() {
|
|
|
+ @Override
|
|
|
+ public T mapRow(ResultSet rs, int i) throws SQLException {
|
|
|
+ try {
|
|
|
+ return handler.handle(resultToOneMap(rs));
|
|
|
+ } catch (Exception e) {
|
|
|
+ logger.error("data convert error," + e.getMessage(), e);
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ if (logger.isDebugEnabled()) {
|
|
|
+ logger.info("SQL<<< cost:{}ms", System.currentTimeMillis() - start);
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ public final <T> List<T> selectList(String sql, Class<T> clz, Object... parameters) {
|
|
|
+ long start = System.currentTimeMillis();
|
|
|
+ if (logger.isInfoEnabled()) {
|
|
|
+ logger.info("selectList 22 SQL>>>:\n{} \nP:{}", sql, JacksonUtil.toJSONString(parameters));
|
|
|
+ }
|
|
|
+
|
|
|
+ List<T> result = jdbcTemplate.query(new PreparedStatementCreator() {
|
|
|
+ @Override
|
|
|
+ public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
|
|
|
+ PreparedStatement preparedStatement = connection.prepareStatement(sql);
|
|
|
+ DbUtil.setParameter(preparedStatement, parameters);
|
|
|
+ return preparedStatement;
|
|
|
+ }
|
|
|
+ }, new RowMapper<T>() {
|
|
|
+ @Override
|
|
|
+ public T mapRow(ResultSet rs, int i) throws SQLException {
|
|
|
+ Map<String, Object> map = resultToOneMap(rs);
|
|
|
+ try {
|
|
|
+ return map2Object(clz, map);
|
|
|
+ } catch (Exception e) {
|
|
|
+ logger.error("data convert error," + e.getMessage(), e);
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+/* List<T> result = jdbcTemplate.query(connection -> {
|
|
|
+ PreparedStatement preparedStatement = connection.prepareStatement(sql);
|
|
|
+ DbUtil.setParameter(preparedStatement, parameters);
|
|
|
+ return preparedStatement;
|
|
|
+ }, (rs, i) -> {
|
|
|
+ Map<String, Object> map = resultToMap(rs);
|
|
|
+ try {
|
|
|
+ return map2Object(clz, map);
|
|
|
+ } catch (Exception e) {
|
|
|
+ logger.error("data convert error," + e.getMessage(), e);
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ });*/
|
|
|
+
|
|
|
+ if (logger.isDebugEnabled()) {
|
|
|
+ logger.info("SQL<<< cost:{}ms", System.currentTimeMillis() - start);
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public final Map<Integer, String> call(String sql, Object... parameters) {
|
|
|
+ int parameterLength = parameters.length;
|
|
|
+ int count = 0;
|
|
|
+ char[] chars = sql.toCharArray();
|
|
|
+ for (char aChar : chars) {
|
|
|
+ if (aChar == '?') {
|
|
|
+ count++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ long start = System.currentTimeMillis();
|
|
|
+ if (logger.isInfoEnabled()) {
|
|
|
+ logger.info("SQL>>>:\n{} \nP:{}", sql, JacksonUtil.toJSONString(parameters));
|
|
|
+ }
|
|
|
+ int finalCount = count;
|
|
|
+ Map<Integer, String> data = (Map<Integer, String>) jdbcTemplate.execute(new CallableStatementCreator() {
|
|
|
+ @Override
|
|
|
+ public CallableStatement createCallableStatement(Connection conn) throws SQLException {
|
|
|
+ CallableStatement cs = conn.prepareCall(sql);
|
|
|
+ DbUtil.setParameter(cs, parameters);
|
|
|
+ //注册输出参数的类型
|
|
|
+ if (finalCount > 0 && finalCount > parameterLength) {
|
|
|
+ for (int j = parameterLength + 1; j <= finalCount; j++) {
|
|
|
+ cs.registerOutParameter(j, Types.VARCHAR);//
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return cs;
|
|
|
+ }
|
|
|
+ }, new CallableStatementCallback<Map<Integer, String>>() {
|
|
|
+ @Override
|
|
|
+ public Map<Integer, String> doInCallableStatement(CallableStatement cs) throws SQLException, DataAccessException {
|
|
|
+ cs.execute();
|
|
|
+ Map<Integer, String> result = new HashMap<>();
|
|
|
+ if (finalCount > 0 && finalCount > parameterLength) {
|
|
|
+ for (int j = parameterLength + 1; j <= finalCount; j++) {
|
|
|
+ cs.registerOutParameter(j, Types.VARCHAR);//
|
|
|
+ result.put(j, cs.getString(j));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return result;// 获取输出参数的值
|
|
|
+ }
|
|
|
+ });
|
|
|
+ if (logger.isDebugEnabled()) {
|
|
|
+ logger.info("SQL<<< cost:{}ms", System.currentTimeMillis() - start);
|
|
|
+ }
|
|
|
+ return data;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public final Object selectObject(String sql, Object... parameters) {
|
|
|
+ SQLEntity entity = helper.selectOne(sql, parameters);
|
|
|
+ Map<String, Object> m = queryForMap(entity);
|
|
|
+ if (!DbUtil.isEmptyOrNull(m)) {
|
|
|
+ if (m.size() != 1) {
|
|
|
+ throw new IllegalStateException("SQL ERROR#" + sql);
|
|
|
+ }
|
|
|
+ Optional<Object> optional = m.values().stream().findFirst();
|
|
|
+ return optional.get();
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 仅适用于查询单一字段的集合
|
|
|
+ */
|
|
|
+ public final List<Object> selectObjects(String sql, Object... parameters) {
|
|
|
+ SQLEntity entity = helper.selectList(sql, parameters);
|
|
|
+ List<Map> rs = queryForList(entity, Map.class);
|
|
|
+ List<Object> result = new ArrayList<>();
|
|
|
+ if (!DbUtil.isEmptyOrNull(rs)) {
|
|
|
+ rs.forEach(item -> {
|
|
|
+ Set<Map.Entry<String, Object>> entrys = item.entrySet();
|
|
|
+ for (Map.Entry<String, Object> entry : entrys) {
|
|
|
+ result.add(entry.getValue());
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ }
|
|
|
+ /* jdbcTemplate.query(connection -> {
|
|
|
+ PreparedStatement ps = connection.prepareStatement(entity.sql);
|
|
|
+ DbUtil.setParameter(ps, entity.parameters);
|
|
|
+ return ps;
|
|
|
+ }, resultSet -> {
|
|
|
+ Map<String, Object> m = resultToMap(resultSet);
|
|
|
+
|
|
|
+ });*/
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public final Integer selectInteger(String sql, Object... parameters) {
|
|
|
+ Object object = selectObject(sql, parameters);
|
|
|
+ if (null != object) {
|
|
|
+ return (int) object;
|
|
|
+ } else {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public final Long selectLong(String sql, Object... parameters) {
|
|
|
+ Object object = selectObject(sql, parameters);
|
|
|
+ if (null != object) {
|
|
|
+ return (long) object;
|
|
|
+ } else {
|
|
|
+ return 0L;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private Map<String, Object> queryForMap(SQLEntity entity) {
|
|
|
+ long start = System.currentTimeMillis();
|
|
|
+ if (logger.isInfoEnabled()) {
|
|
|
+ logger.info("SQL>>>:\n{} \nP:{}", entity.sql, JacksonUtil.toJSONString(entity.parameters));
|
|
|
+ }
|
|
|
+ //处理json函数
|
|
|
+ Map<String, Object> result = jdbcTemplate.query(new PreparedStatementCreator() {
|
|
|
+ @Override
|
|
|
+ public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
|
|
|
+ PreparedStatement ps = connection.prepareStatement(entity.sql);
|
|
|
+ DbUtil.setParameter(ps, entity.parameters);
|
|
|
+ return ps;
|
|
|
+ }
|
|
|
+ }, new ResultSetExtractor<Map<String, Object>>() {
|
|
|
+ @Override
|
|
|
+ public Map<String, Object> extractData(ResultSet resultSet) throws SQLException, DataAccessException {
|
|
|
+ return extractResultToOneMap(resultSet);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ if (logger.isDebugEnabled()) {
|
|
|
+ logger.info("SQL<<< cost:{}ms", System.currentTimeMillis() - start);
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ public final <T> double selectFunc(int funcType, Class<?> entityClz, ColumnFunc<T, ?> keyExtractor, OBuilder OBuilder) {
|
|
|
+ String func = switch (funcType) {
|
|
|
+ case FUNC_AVG -> "avg";
|
|
|
+ case FUNC_COUNT -> "count";
|
|
|
+ case FUNC_MIN -> "min";
|
|
|
+ case FUNC_MAX -> "max";
|
|
|
+ case FUNC_SUM -> "sum";
|
|
|
+ default -> throw new IllegalArgumentException("illegal argument for func type#:" + funcType);
|
|
|
+ };
|
|
|
+ func += "(" + getColumnName(DefaultLambdaParser.getPropertyName(keyExtractor)) + ")";
|
|
|
+ SQLEntity entity = helper.selectFunc(entityClz, func, OBuilder);
|
|
|
+ Map<String, Object> m = queryForMap(entity);
|
|
|
+ if (!DbUtil.isEmptyOrNull(m)) {
|
|
|
+ if (m.size() != 1) {
|
|
|
+ throw new IllegalStateException("SQL ERROR# result count is not equal one!!!");
|
|
|
+ }
|
|
|
+ Collection<Object> values = m.values();
|
|
|
+ if (DbUtil.isEmptyOrNull(values)) {
|
|
|
+ return 0d;
|
|
|
+ }
|
|
|
+ Optional<Object> optional = values.stream().filter(k -> !DbUtil.isEmptyOrNull(k)).findFirst();
|
|
|
+ if (optional.isPresent()) {
|
|
|
+ Object obj = optional.get();
|
|
|
+ if (obj instanceof BigDecimal) {
|
|
|
+ return ((BigDecimal) obj).doubleValue();
|
|
|
+ } else {
|
|
|
+ return Double.parseDouble(obj.toString());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return 0d;
|
|
|
+ }
|
|
|
+
|
|
|
+ public final List<Object> selectDistinct(Class<?> clz, String key, OBuilder oBuilder) {
|
|
|
+ SQLEntity entity = helper.selectDistinct(clz, "DISTINCT(" + getColumnName(key) + ")", oBuilder);
|
|
|
+ List<Map> resultList = queryForList(entity, Map.class);
|
|
|
+ List<Object> objects = new ArrayList<>();
|
|
|
+ if (!DbUtil.isEmptyOrNull(resultList)) {
|
|
|
+ for (Map<String, Object> map : resultList) {
|
|
|
+ if (!DbUtil.isEmptyOrNull(map)) {
|
|
|
+ Set<Map.Entry<String, Object>> entrys = map.entrySet();
|
|
|
+ for (Map.Entry<String, Object> entry : entrys) {
|
|
|
+ objects.add(entry.getValue());
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return objects;
|
|
|
+ }
|
|
|
+
|
|
|
+ private <T> T queryForSingleObject(SQLEntity entity, Class<T> clz) {
|
|
|
+ Map<String, Object> map = queryForMap(entity);
|
|
|
+ if (!DbUtil.isEmptyOrNull(map)) {
|
|
|
+ Object value = null;
|
|
|
+ Set<Map.Entry<String, Object>> entrys = map.entrySet();
|
|
|
+ for (Map.Entry<String, Object> entry : entrys) {
|
|
|
+ value = entry.getValue();
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if (null != value) {
|
|
|
+ return JacksonUtil.toJavaObject(value.toString(), clz);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public final long selectCount(Class<?> clz, OBuilder oBuilder) {
|
|
|
+ beforeSelect(clz, oBuilder);
|
|
|
+ SQLEntity entity = helper.selectCount(clz, oBuilder);
|
|
|
+ Long result = queryForSingleObject(entity, Long.class);
|
|
|
+ if (null == result) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public final long selectCount(BasicQuery query) {
|
|
|
+ beforeSelect(query);
|
|
|
+ query.pageSize = -1;
|
|
|
+ SQLEntity entity = helper.selectCountByQuery(query);
|
|
|
+ Long result = queryForSingleObject(entity, Long.class);
|
|
|
+ if (null == result) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ public final Map<String, Object> selectOneForMap(String sql, Object... parameters) {
|
|
|
+ long start = System.currentTimeMillis();
|
|
|
+ if (logger.isInfoEnabled()) {
|
|
|
+ logger.info("SQL>>>:\n{} \nP:{}", sql, JacksonUtil.toJSONString(parameters));
|
|
|
+ }
|
|
|
+ Map<String, Object> result = jdbcTemplate.query(new PreparedStatementCreator() {
|
|
|
+ @Override
|
|
|
+ public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
|
|
|
+ PreparedStatement preparedStatement = connection.prepareStatement(sql);
|
|
|
+ DbUtil.setParameter(preparedStatement, parameters);
|
|
|
+ return preparedStatement;
|
|
|
+ }
|
|
|
+ }, new ResultSetExtractor<Map<String, Object>>() {
|
|
|
+ @Override
|
|
|
+ public Map<String, Object> extractData(ResultSet resultSet) throws SQLException, DataAccessException {
|
|
|
+ return resultToOneMap(resultSet);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ if (logger.isDebugEnabled()) {
|
|
|
+ logger.info("SQL<<< cost:{}ms", System.currentTimeMillis() - start);
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public final <T> T selectOne(String sql, ResultHandler<T> handler, Object... parameters) {
|
|
|
+ long start = System.currentTimeMillis();
|
|
|
+ if (logger.isInfoEnabled()) {
|
|
|
+ logger.info("SQL>>>:\n{} \nP:{}", sql, JacksonUtil.toJSONString(parameters));
|
|
|
+ }
|
|
|
+ T result = jdbcTemplate.query(new PreparedStatementCreator() {
|
|
|
+ @Override
|
|
|
+ public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
|
|
|
+ PreparedStatement preparedStatement = connection.prepareStatement(sql);
|
|
|
+ DbUtil.setParameter(preparedStatement, parameters);
|
|
|
+ return preparedStatement;
|
|
|
+ }
|
|
|
+ }, new ResultSetExtractor<T>() {
|
|
|
+ @Override
|
|
|
+ public T extractData(ResultSet resultSet) throws SQLException, DataAccessException {
|
|
|
+ Map<String, Object> map = resultToOneMap(resultSet);
|
|
|
+ try {
|
|
|
+ return handler.handle(map);
|
|
|
+ } catch (Exception e) {
|
|
|
+ logger.error("data convert error," + e.getMessage(), e);
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ if (logger.isDebugEnabled()) {
|
|
|
+ logger.info("SQL<<< cost:{}ms", System.currentTimeMillis() - start);
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<Map<String, Object>> resultToListMap(ResultSet rs) throws SQLException {
|
|
|
+ List<Map<String, Object>> result = new ArrayList<>();
|
|
|
+ if (null != rs) {
|
|
|
+ ResultSetMetaData rsmd = rs.getMetaData();
|
|
|
+ while (rs.next()) {
|
|
|
+ Map<String, Object> map = new HashMap<>(16);
|
|
|
+ int columnCount = rsmd.getColumnCount();
|
|
|
+ for (int i = 0; i < columnCount; i++) {
|
|
|
+ String columnLabel = rsmd.getColumnLabel(i + 1);
|
|
|
+ map.put(columnLabel, rs.getObject(i + 1));
|
|
|
+ }
|
|
|
+ result.add(map);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ private Map<String, Object> resultToOneMap(ResultSet rs) throws SQLException {
|
|
|
+ Map<String, Object> map = new HashMap<>();
|
|
|
+ if (null != rs) {
|
|
|
+ ResultSetMetaData rsmd = rs.getMetaData();
|
|
|
+ int columnCount = rsmd.getColumnCount();
|
|
|
+// while (rs.next()) {
|
|
|
+ for (int i = 0; i < columnCount; i++) {
|
|
|
+ String columnLabel = rsmd.getColumnLabel(i + 1);
|
|
|
+ map.put(columnLabel, rs.getObject(i + 1));
|
|
|
+ }
|
|
|
+// }
|
|
|
+ }
|
|
|
+ return map;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private Map<String, Object> extractResultToOneMap(ResultSet rs) throws SQLException {
|
|
|
+ Map<String, Object> map = new HashMap<>();
|
|
|
+ if (null != rs) {
|
|
|
+ ResultSetMetaData rsmd = rs.getMetaData();
|
|
|
+ int columnCount = rsmd.getColumnCount();
|
|
|
+ while (rs.next()) {
|
|
|
+ for (int i = 0; i < columnCount; i++) {
|
|
|
+ String columnLabel = rsmd.getColumnLabel(i + 1);
|
|
|
+ map.put(columnLabel, rs.getObject(i + 1));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return map;
|
|
|
+ }
|
|
|
+
|
|
|
+ public final <T> T selectOne(Class<T> clz, ColumnFunc<T, ?> keyExtractor, Object value) {
|
|
|
+ SQLEntity entity = helper.selectOneByWhere(clz, OBuilder.build().eq(DefaultLambdaParser.getPropertyName(keyExtractor), value), null, null);
|
|
|
+ Map<String, Object> map = queryForMap(entity);
|
|
|
+ T t = map2Object(clz, map);
|
|
|
+ //Annotation @Many
|
|
|
+ if (null != t) {
|
|
|
+ setJoinList(t, clz, null);
|
|
|
+ }
|
|
|
+ return t;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public final <T> T selectOne(Class<T> clz, String fieldName, Object value) {
|
|
|
+ SQLEntity entity = helper.selectOneByWhere(clz, OBuilder.build().eq(fieldName, value), null, null);
|
|
|
+ Map<String, Object> map = queryForMap(entity);
|
|
|
+ T t = map2Object(clz, map);
|
|
|
+ //Annotation @Many
|
|
|
+ if (null != t) {
|
|
|
+ setJoinList(t, clz, null);
|
|
|
+ }
|
|
|
+ return t;
|
|
|
+ }
|
|
|
+
|
|
|
+ public final <T> T selectOne(Class<T> clz, long id, String... include) {
|
|
|
+ SQLEntity entity = helper.selectById(clz, id, Arrays.asList(include), null);
|
|
|
+ Map<String, Object> map = queryForMap(entity);
|
|
|
+ T t = map2Object(clz, map);
|
|
|
+ //Annotation @Many
|
|
|
+ if (null != t) {
|
|
|
+ setJoinList(t, clz, null);
|
|
|
+ }
|
|
|
+ return t;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public final <T> T selectOneExclude(Class<T> clz, long id, String... exclude) {
|
|
|
+ SQLEntity entity = helper.selectById(clz, id, null, Arrays.asList(exclude));
|
|
|
+ Map<String, Object> map = queryForMap(entity);
|
|
|
+ T t = map2Object(clz, map);
|
|
|
+ //Annotation @Many
|
|
|
+ if (null != t) {
|
|
|
+ setJoinList(t, clz, Arrays.asList(exclude));
|
|
|
+ }
|
|
|
+ return t;
|
|
|
+ }
|
|
|
+
|
|
|
+ public final <T> T selectOneExist(Class<T> clz, long id) {
|
|
|
+ T bean = selectOne(clz, id);
|
|
|
+ if (null == bean) {
|
|
|
+ throw new IllegalArgumentException(clz.getAnnotation(Entity.class).comment() + "不存在");
|
|
|
+ }
|
|
|
+ return bean;
|
|
|
+ }
|
|
|
+
|
|
|
+ public final <T> T selectOneExist(Class<T> clz, OBuilder builder) {
|
|
|
+ beforeSelect(clz, builder);
|
|
|
+ T bean = selectOne(clz, builder);
|
|
|
+ if (null == bean) {
|
|
|
+ throw new IllegalArgumentException(clz.getAnnotation(Entity.class).comment() + "不存在");
|
|
|
+ }
|
|
|
+ return bean;
|
|
|
+ }
|
|
|
+
|
|
|
+ public final <T> T selectOne(Class<T> clz, OBuilder builder) {
|
|
|
+ beforeSelect(clz, builder);
|
|
|
+ SQLEntity entity = helper.selectOneByWhere(clz, builder, null, null);
|
|
|
+ Map<String, Object> map = queryForMap(entity);
|
|
|
+ T t = map2Object(clz, map);
|
|
|
+ //Annotation @Many
|
|
|
+ if (null != t) {
|
|
|
+ setJoinList(t, clz, null);
|
|
|
+ }
|
|
|
+ return t;
|
|
|
+ }
|
|
|
+
|
|
|
+ public final <T> T selectOne(Class<T> clz, OBuilder builder, List<String> includes) {
|
|
|
+ beforeSelect(clz, builder);
|
|
|
+ SQLEntity entity = helper.selectOneByWhere(clz, builder, includes, null);
|
|
|
+ Map<String, Object> map = queryForMap(entity);
|
|
|
+ T t = map2Object(clz, map);
|
|
|
+ //Annotation @Many
|
|
|
+ if (null != t) {
|
|
|
+ setJoinList(t, clz, null);
|
|
|
+ }
|
|
|
+ return t;
|
|
|
+ }
|
|
|
+
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
+ public final <T> T selectOne(BasicQuery query, String... include) {
|
|
|
+ beforeSelect(query);
|
|
|
+ SQLEntity entity = helper.selectOneByQuery(query, Arrays.asList(include), null);
|
|
|
+ Map<String, Object> map = queryForMap(entity);
|
|
|
+ Class<T> clz = (Class<T>) query.getClass().getAnnotation(QE.class).clz();
|
|
|
+ T t = map2Object(clz, map);
|
|
|
+ //Annotation @Many
|
|
|
+ if (null != t) {
|
|
|
+ setJoinList(t, clz, null);
|
|
|
+ }
|
|
|
+ return t;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
+ public final <T> T selectOneExclude(BasicQuery query, String... exclude) {
|
|
|
+ beforeSelect(query);
|
|
|
+ SQLEntity entity = helper.selectOneByQuery(query, null, Arrays.asList(exclude));
|
|
|
+ Map<String, Object> map = queryForMap(entity);
|
|
|
+ Class<T> clz = (Class<T>) query.getClass().getAnnotation(QE.class).clz();
|
|
|
+ T t = map2Object(clz, map);
|
|
|
+ //Annotation @Many
|
|
|
+ if (null != t) {
|
|
|
+ setJoinList(t, clz, Arrays.asList(exclude));
|
|
|
+ }
|
|
|
+ return t;
|
|
|
+ }
|
|
|
+
|
|
|
+ public final <T> T selectField(Class<?> clz, String fieldName, OBuilder OBuilder, Class<T> rspClz) {
|
|
|
+ String sql = "select " + getColumnName(fieldName) + " as f0 from " + getTableName(clz.getSimpleName()) + " where " + OBuilder.toSql();
|
|
|
+ return selectOne(sql, rs -> JacksonUtil.toJavaObject(rs.get("f0"), rspClz));
|
|
|
+ }
|
|
|
+
|
|
|
+ public final <T> T selectField(Class<?> clz, ColumnFunc<T, ?> keyExtractor, OBuilder OBuilder, Class<T> rspClz) {
|
|
|
+ String sql = "select " + getColumnName(DefaultLambdaParser.getPropertyName(keyExtractor)) + " as f0 from " + getTableName(clz.getSimpleName()) + " where " + OBuilder.toSql();
|
|
|
+ return selectOne(sql, rs -> JacksonUtil.toJavaObject(rs.get("f0"), rspClz));
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ //endregion
|
|
|
+
|
|
|
+
|
|
|
+ //region insert
|
|
|
+
|
|
|
+ /**
|
|
|
+ * ------------insert------------
|
|
|
+ */
|
|
|
+ public final long insert(Object bean) {
|
|
|
+ beforeInsert(bean);
|
|
|
+ long id = insert(bean, false, false, "id");
|
|
|
+ setFieldValue(bean, "id", id);
|
|
|
+ return id;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 插入记录(无id返回)
|
|
|
+ */
|
|
|
+ public final void insertOnly(Object bean) {
|
|
|
+ beforeInsert(bean);
|
|
|
+ insert(bean, false, true, "id");
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 插入非空值
|
|
|
+ */
|
|
|
+ public final long insertSelective(Object bean, String... exclude) {
|
|
|
+ beforeInsert(bean);
|
|
|
+ List<String> exs = new ArrayList<>();
|
|
|
+ if (!DbUtil.isEmptyOrNull(exclude)) {
|
|
|
+ exs.addAll(Arrays.asList(exclude));
|
|
|
+ }
|
|
|
+ SQLEntity entity = helper.insertSelective(bean, exs);
|
|
|
+ long id = executeInsert(entity, true);
|
|
|
+ setFieldValue(bean, "id", id);
|
|
|
+ return id;
|
|
|
+ }
|
|
|
+
|
|
|
+ private long executeInsert(SQLEntity entity, boolean returnKey) {
|
|
|
+ long result = 0;
|
|
|
+ long start = System.currentTimeMillis();
|
|
|
+ if (logger.isInfoEnabled()) {
|
|
|
+ logger.info("SQL>>>:\n{} \nP:{}", entity.sql, JacksonUtil.toJSONString(entity.parameters));
|
|
|
+ }
|
|
|
+ if (returnKey) {
|
|
|
+ KeyHolder keyHolder = new GeneratedKeyHolder();
|
|
|
+ jdbcTemplate.update(new PreparedStatementCreator() {
|
|
|
+ @Override
|
|
|
+ public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
|
|
|
+ if (helper.getDialect() == JdbcHelper.DIALECT_PGSQL) {
|
|
|
+ PreparedStatement ps = connection.prepareStatement(entity.sql, new String[]{"id"});
|
|
|
+ DbUtil.setParameter(ps, entity.parameters);
|
|
|
+ return ps;
|
|
|
+ }
|
|
|
+ if (helper.getDialect() == JdbcHelper.DIALECT_MYSQL) {
|
|
|
+ PreparedStatement ps = connection.prepareStatement(entity.sql, PreparedStatement.RETURN_GENERATED_KEYS);
|
|
|
+ DbUtil.setParameter(ps, entity.parameters);
|
|
|
+ return ps;
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }, keyHolder);
|
|
|
+ Number number = keyHolder.getKey();
|
|
|
+ long id = -1;
|
|
|
+ if (null != number) {
|
|
|
+ id = number.longValue();
|
|
|
+ }
|
|
|
+ result = id;
|
|
|
+ } else {
|
|
|
+ jdbcTemplate.update(connection -> {
|
|
|
+ PreparedStatement ps = connection.prepareStatement(entity.sql);
|
|
|
+ DbUtil.setParameter(ps, entity.parameters);
|
|
|
+ return ps;
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ if (logger.isDebugEnabled()) {
|
|
|
+ logger.info("SQL<<< cost:{}ms", System.currentTimeMillis() - start);
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 插入非空值(无id返回)
|
|
|
+ */
|
|
|
+ public final void insertSelectiveOnly(Object bean, String... exclude) {
|
|
|
+ beforeInsert(bean);
|
|
|
+ SQLEntity entity = helper.insertSelective(bean, Arrays.asList(exclude));
|
|
|
+ executeInsert(entity, false);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param withGenKey 是否主动生成ID主键<br>
|
|
|
+ * 主键策略可以使用{@link com.kym.common.utils.sequence.IdWorker.nextId} ,避免高并发情况下通过#lastInsertId获取id错误的情况
|
|
|
+ */
|
|
|
+ public final long insert(Object bean, boolean withGenKey, boolean insertOnly, String... exclude) {
|
|
|
+ beforeInsert(bean);
|
|
|
+ if (!withGenKey) {
|
|
|
+ SQLEntity entity = helper.insert(bean, new ArrayList<>(Arrays.asList(exclude)));
|
|
|
+ return executeInsert(entity, !insertOnly);
|
|
|
+ } else {
|
|
|
+ Object id = getFieldValue(bean, "id");
|
|
|
+ if (DbUtil.isEmptyOrNull(id)) {
|
|
|
+ throw new IllegalArgumentException("without id exist for insert withGenKey");
|
|
|
+ }
|
|
|
+ SQLEntity entity = helper.insertWithGenKey(bean, new ArrayList<>(Arrays.asList(exclude)));
|
|
|
+ executeInsert(entity, false);
|
|
|
+ return (long) getFieldValue(bean, "id");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public final void insertBatch(List<?> dtoList) {
|
|
|
+ if (DbUtil.isEmptyOrNull(dtoList)) {
|
|
|
+ logger.info("insertBatch no dtoList exists!!!");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ List<String> ignores = Arrays.asList("id".split(","));
|
|
|
+ Set<Field> fields = DbUtil.getEntityFields(dtoList.get(0).getClass());
|
|
|
+ List<String> fieldList = new ArrayList<>();
|
|
|
+ for (Field field : fields) {
|
|
|
+ int modifier = field.getModifiers();
|
|
|
+ if (!Modifier.isFinal(modifier) && !Modifier.isStatic(modifier) && field.isAnnotationPresent(DBF.class)) {
|
|
|
+ String fieldName = field.getName();
|
|
|
+ if (!ignores.contains(fieldName)) {
|
|
|
+ fieldList.add(field.getName());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ insertBatch(fieldList, dtoList);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 需自己组装SQL语句
|
|
|
+ */
|
|
|
+ public final void insertBatch(String sql, List<Object[]> parameters) {
|
|
|
+ long start = System.currentTimeMillis();
|
|
|
+ if (logger.isInfoEnabled()) {
|
|
|
+ logger.info("SQL>>>:\n{} \nP:{}", sql, JacksonUtil.toJSONString(parameters));
|
|
|
+ }
|
|
|
+ int batch = 1;
|
|
|
+ int batchSize = 256;
|
|
|
+ int totalSize = parameters.size();
|
|
|
+ if (totalSize > batchSize) {
|
|
|
+ batch = (int) Math.ceil((double) totalSize / batchSize);
|
|
|
+ }
|
|
|
+ for (int i = 0; i < batch; i++) {
|
|
|
+ List<Object[]> subList = parameters.subList(i * batchSize, Math.min(totalSize, ((i + 1) * batchSize)));
|
|
|
+ jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
|
|
|
+ @Override
|
|
|
+ public void setValues(PreparedStatement preparedStatement, int i) throws SQLException {
|
|
|
+ DbUtil.setParameter(preparedStatement, subList.get(i));
|
|
|
+// preparedStatement.addBatch();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public int getBatchSize() {
|
|
|
+ return subList.size();
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if (logger.isDebugEnabled()) {
|
|
|
+ logger.info("SQL<<< cost:{}ms", System.currentTimeMillis() - start);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 无需自己组装SQL
|
|
|
+ */
|
|
|
+ public final void insertBatch(List<String> fields, List<?> dtoList) {
|
|
|
+ if (DbUtil.isEmptyOrNull(fields)) {
|
|
|
+ throw new IllegalArgumentException("ERROR# insert fields is empty!");
|
|
|
+ }
|
|
|
+ if (DbUtil.isEmptyOrNull(dtoList)) {
|
|
|
+ throw new IllegalArgumentException("ERROR# insert values is empty!");
|
|
|
+ }
|
|
|
+ StringBuilder sql = new StringBuilder("insert into ");
|
|
|
+ String tbName = dtoList.get(0).getClass().getSimpleName();
|
|
|
+ sql.append(getTableName(tbName)).append(" ( ");
|
|
|
+ sql.append(fields.stream().map(this::getColumnName).collect(Collectors.joining(",")));
|
|
|
+ sql.append(" ) values (");
|
|
|
+ sql.append(fields.stream().map(k -> "?").collect(Collectors.joining(",")));
|
|
|
+ sql.append(")");
|
|
|
+
|
|
|
+ List<Object[]> params = new ArrayList<>();
|
|
|
+ int fieldSize = fields.size();
|
|
|
+ for (Object o : dtoList) {
|
|
|
+ Object[] ll = new Object[fieldSize];
|
|
|
+ for (int j = 0; j < fieldSize; j++) {
|
|
|
+ ll[j] = getFieldValue(o, fields.get(j));
|
|
|
+ }
|
|
|
+ params.add(ll);
|
|
|
+ }
|
|
|
+
|
|
|
+ int totalSize = params.size();
|
|
|
+ long start = System.currentTimeMillis();
|
|
|
+ if (logger.isInfoEnabled()) {
|
|
|
+ logger.info("SQL>>>:\n{} \nP:{}", sql, totalSize > 20 ? params.size() : JacksonUtil.toJSONString(params));
|
|
|
+ }
|
|
|
+
|
|
|
+ if (DbUtil.isEmptyOrNull(params)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ int batch = 1;
|
|
|
+ int batchSize = 256;
|
|
|
+ if (totalSize > batchSize) {
|
|
|
+ batch = (int) Math.ceil((double) totalSize / batchSize);
|
|
|
+ }
|
|
|
+ for (int i = 0; i < batch; i++) {
|
|
|
+ List<Object[]> subList = params.subList(i * batchSize, Math.min(totalSize, ((i + 1) * batchSize)));
|
|
|
+ jdbcTemplate.batchUpdate(sql.toString(), new BatchPreparedStatementSetter() {
|
|
|
+ @Override
|
|
|
+ public void setValues(PreparedStatement preparedStatement, int i) throws SQLException {
|
|
|
+// logger.info("i>>>>>>>" + i);
|
|
|
+ DbUtil.setParameter(preparedStatement, subList.get(i));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public int getBatchSize() {
|
|
|
+ return subList.size();
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if (logger.isDebugEnabled()) {
|
|
|
+ logger.info("SQL<<< cost:{}ms", System.currentTimeMillis() - start);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //endregion
|
|
|
+
|
|
|
+ //region update
|
|
|
+
|
|
|
+ /**
|
|
|
+ * ------------update------------
|
|
|
+ */
|
|
|
+
|
|
|
+ private int executeUpdate(SQLEntity entity) {
|
|
|
+ long start = System.currentTimeMillis();
|
|
|
+ if (logger.isInfoEnabled()) {
|
|
|
+ logger.info("SQL>>>:\n{} \nP:{}", entity.sql, JacksonUtil.toJSONString(entity.parameters));
|
|
|
+ }
|
|
|
+ int result = jdbcTemplate.update(connection -> {
|
|
|
+ PreparedStatement ps = connection.prepareStatement(entity.sql);
|
|
|
+ DbUtil.setParameter(ps, entity.parameters);
|
|
|
+ return ps;
|
|
|
+ });
|
|
|
+ if (logger.isDebugEnabled()) {
|
|
|
+ logger.info("SQL<<< cost:{}ms", System.currentTimeMillis() - start);
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ public final int update(Object bean) {
|
|
|
+ checkConditionOnUpdate(bean);
|
|
|
+ beforeUpdate(bean);
|
|
|
+ SQLEntity entity = helper.updateByWhere(bean, OBuilder.build());
|
|
|
+ int count = executeUpdate(entity);
|
|
|
+ if (count == 0) {
|
|
|
+ logger.warn("SQLHandler WARN# update with no record effects");
|
|
|
+ } else {
|
|
|
+ logger.debug("update effect rows:{}", count);
|
|
|
+ }
|
|
|
+ return count;
|
|
|
+ }
|
|
|
+
|
|
|
+ public final int update(String sql, Object... parameters) {
|
|
|
+ SQLEntity entity = helper.update(sql, parameters);
|
|
|
+ int count = executeUpdate(entity);
|
|
|
+ if (count == 0) {
|
|
|
+ logger.warn("SQLHandler WARN# update with no record effects#SQL:{},PARAMS:{}", sql, JacksonUtil.toJSONString(parameters));
|
|
|
+ } else {
|
|
|
+ logger.debug("update effect rows:{}", count);
|
|
|
+ }
|
|
|
+ return count;
|
|
|
+ }
|
|
|
+
|
|
|
+ public final int update(Object bean, OBuilder builder) {
|
|
|
+ checkConditionOnUpdate(builder);
|
|
|
+ beforeUpdate(bean, builder);
|
|
|
+ SQLEntity entity = helper.updateByWhere(bean, builder);
|
|
|
+ int count = executeUpdate(entity);
|
|
|
+ if (count == 0) {
|
|
|
+ logger.warn("SQLHandler WARN# update with no record effects");
|
|
|
+ } else {
|
|
|
+ logger.debug("update effect rows:{}", count);
|
|
|
+ }
|
|
|
+ return count;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public final <T> int update(Object bean, OBuilder builder, ColumnFunc<T, ?> keyExtractor) {
|
|
|
+ checkConditionOnUpdate(builder);
|
|
|
+ beforeUpdate(bean, builder);
|
|
|
+ List<String> includes = new ArrayList<>();
|
|
|
+ if (!DbUtil.isEmptyOrNull(keyExtractor)) {
|
|
|
+ includes.add(DefaultLambdaParser.getPropertyName(keyExtractor));
|
|
|
+ }
|
|
|
+ SQLEntity entity = helper.updateByWhere(bean, builder, includes);
|
|
|
+ int count = executeUpdate(entity);
|
|
|
+ if (count == 0) {
|
|
|
+ logger.warn("SQLHandler WARN# update with no record effects");
|
|
|
+ } else {
|
|
|
+ logger.debug("update effect rows:{}", count);
|
|
|
+ }
|
|
|
+ return count;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 部分字段更新(为空、为0不更新)
|
|
|
+ */
|
|
|
+ public final int updateSelective(Object bean) {
|
|
|
+ checkConditionOnUpdate(bean);
|
|
|
+ beforeUpdate(bean);
|
|
|
+ SQLEntity entity = helper.updateSelective(bean, null, null);
|
|
|
+ int count = executeUpdate(entity);
|
|
|
+ if (count == 0) {
|
|
|
+ logger.warn("SQLHandler WARN# update with no record effects");
|
|
|
+ } else {
|
|
|
+ logger.debug("update effect rows:{}", count);
|
|
|
+ }
|
|
|
+ return count;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 只更新指定字段
|
|
|
+ */
|
|
|
+ public final int updateSelective(Object bean, String... includes) {
|
|
|
+ checkConditionOnUpdate(bean);
|
|
|
+ beforeUpdate(bean);
|
|
|
+ List<String> ic = new ArrayList<>();
|
|
|
+ if (!DbUtil.isEmptyOrNull(includes)) {
|
|
|
+ ic = Arrays.asList(includes);
|
|
|
+ }
|
|
|
+ SQLEntity entity = helper.updateSelective(bean, ic, null);
|
|
|
+ int count = executeUpdate(entity);
|
|
|
+ if (count == 0) {
|
|
|
+ logger.warn("SQLHandler WARN# update with no record effects");
|
|
|
+ } else {
|
|
|
+ logger.debug("update effect rows:{}", count);
|
|
|
+ }
|
|
|
+ return count;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ @SafeVarargs
|
|
|
+ public final <T> int updateSelective(Object bean, ColumnFunc<T, ?>... keyExtractor) {
|
|
|
+ checkConditionOnUpdate(bean);
|
|
|
+ beforeUpdate(bean);
|
|
|
+ List<String> ic = new ArrayList<>();
|
|
|
+ if (!DbUtil.isEmptyOrNull(keyExtractor)) {
|
|
|
+ for (ColumnFunc<T, ?> func : keyExtractor) {
|
|
|
+ ic.add(DefaultLambdaParser.getPropertyName(func));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ SQLEntity entity = helper.updateSelective(bean, ic, null);
|
|
|
+ int count = executeUpdate(entity);
|
|
|
+ if (count == 0) {
|
|
|
+ logger.warn("SQLHandler WARN# update with no record effects");
|
|
|
+ } else {
|
|
|
+ logger.debug("update effect rows:{}", count);
|
|
|
+ }
|
|
|
+ return count;
|
|
|
+ }
|
|
|
+
|
|
|
+ public final int updateSelectiveExclude(Object bean, String... excludes) {
|
|
|
+ checkConditionOnUpdate(bean);
|
|
|
+ beforeUpdate(bean);
|
|
|
+ List<String> ec = new ArrayList<>();
|
|
|
+ if (!DbUtil.isEmptyOrNull(excludes)) {
|
|
|
+ ec = Arrays.asList(excludes);
|
|
|
+ }
|
|
|
+ SQLEntity entity = helper.updateSelective(bean, null, ec);
|
|
|
+ int count = executeUpdate(entity);
|
|
|
+ if (count == 0) {
|
|
|
+ logger.warn("SQLHandler WARN# update with no record effects");
|
|
|
+ } else {
|
|
|
+ logger.debug("update effect rows:{}", count);
|
|
|
+ }
|
|
|
+ return count;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public final <T> int updateSelectiveExclude(Object bean, ColumnFunc<T, ?>... exkeyExtractor) {
|
|
|
+ checkConditionOnUpdate(bean);
|
|
|
+ beforeUpdate(bean);
|
|
|
+ List<String> ec = new ArrayList<>();
|
|
|
+ if (!DbUtil.isEmptyOrNull(exkeyExtractor)) {
|
|
|
+ for (ColumnFunc<T, ?> tColumnFunc : exkeyExtractor) {
|
|
|
+ ec.add(DefaultLambdaParser.getPropertyName(tColumnFunc));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ SQLEntity entity = helper.updateSelective(bean, null, ec);
|
|
|
+ int count = executeUpdate(entity);
|
|
|
+ if (count == 0) {
|
|
|
+ logger.warn("SQLHandler WARN# update with no record effects");
|
|
|
+ } else {
|
|
|
+ logger.debug("update effect rows:{}", count);
|
|
|
+ }
|
|
|
+ return count;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 部分字段更新(为空、为0不更新)
|
|
|
+ */
|
|
|
+ public final int updateSelective(Object bean, OBuilder OBuilder) {
|
|
|
+ checkConditionOnUpdate(OBuilder);
|
|
|
+ beforeUpdate(bean, OBuilder);
|
|
|
+ SQLEntity entity = helper.updateSelectiveByWhere(bean, OBuilder);
|
|
|
+
|
|
|
+ int count = executeUpdate(entity);
|
|
|
+ if (count == 0) {
|
|
|
+ logger.warn("SQLHandler WARN# update with no record effects");
|
|
|
+ } else {
|
|
|
+ logger.debug("update effect rows:{}", count);
|
|
|
+ }
|
|
|
+
|
|
|
+ return count;
|
|
|
+ }
|
|
|
+
|
|
|
+ public final <T> void updateBatchV2(List<ColumnFunc<T, ?>> keyExtractors, List<?> dtoList) {
|
|
|
+ List<String> fields = new ArrayList<>();
|
|
|
+ keyExtractors.forEach(keyExtractor -> fields.add(DefaultLambdaParser.getPropertyName(keyExtractor)));
|
|
|
+ updateBatch(fields, dtoList);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 批量更新方法
|
|
|
+ *
|
|
|
+ * @param fields
|
|
|
+ * @param dtoList
|
|
|
+ */
|
|
|
+ public final void updateBatch(List<String> fields, List<?> dtoList) {
|
|
|
+ if (DbUtil.isEmptyOrNull(dtoList)) {
|
|
|
+ logger.error("no records to batch update!!!");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (DbUtil.isEmptyOrNull(fields)) {
|
|
|
+ logger.error("no column to batch update!!!");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ List<Object[]> params = new ArrayList<>();
|
|
|
+ for (int i1 = 0; i1 < dtoList.size(); i1++) {
|
|
|
+ Object obj = dtoList.get(i1);
|
|
|
+ Object[] param = new Object[fields.size() + 1];
|
|
|
+ for (int i = 0; i < fields.size(); i++) {
|
|
|
+ param[i] = DbUtil.getFieldValue(obj, DbUtil.getCamelName(fields.get(i)));
|
|
|
+ }
|
|
|
+ Object id = DbUtil.getFieldValue(obj, "id");
|
|
|
+ if (null == id || Long.parseLong(id.toString()) == 0) {
|
|
|
+ logger.error("id is null ,idx:{}", i1);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ param[fields.size()] = id;
|
|
|
+ params.add(param);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ String sql = " update " + JdbcHelper.getTableName(dtoList.get(0).getClass(), dtoList.get(0).getClass().getSimpleName()) + " set " + fields.stream().map(k -> DbUtil.getColumnName(k) + "=?").collect(Collectors.joining(",")) + " where id = ?";
|
|
|
+ updateBatch(sql, params);
|
|
|
+ }
|
|
|
+
|
|
|
+ public final void updateBatch(String sql, List<Object[]> params) {
|
|
|
+ long start = System.currentTimeMillis();
|
|
|
+ if (logger.isInfoEnabled()) {
|
|
|
+ logger.info("SQL>>>:\n{} \nP:{}", sql, params.size() > 20 ? params.size() : JacksonUtil.toJSONString(params));
|
|
|
+ }
|
|
|
+
|
|
|
+ int batch = 1;
|
|
|
+ int batchSize = 256;
|
|
|
+ int totalSize = params.size();
|
|
|
+ if (totalSize > batchSize) {
|
|
|
+ batch = (int) Math.ceil((double) totalSize / batchSize);
|
|
|
+ }
|
|
|
+ for (int i = 0; i < batch; i++) {
|
|
|
+ List<Object[]> subList = params.subList(i * batchSize, Math.min(totalSize, ((i + 1) * batchSize)));
|
|
|
+ jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
|
|
|
+ @Override
|
|
|
+ public void setValues(PreparedStatement preparedStatement, int i) throws SQLException {
|
|
|
+ DbUtil.setParameter(preparedStatement, subList.get(i));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public int getBatchSize() {
|
|
|
+ return subList.size();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ if (logger.isDebugEnabled()) {
|
|
|
+ logger.info("SQL<<< cost:{}ms", System.currentTimeMillis() - start);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ //endregion
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 更新数据必须指定where条件
|
|
|
+ */
|
|
|
+ private void checkConditionOnUpdate(Object bean) {
|
|
|
+ Object val = getFieldValue(bean, "id");
|
|
|
+ if (null == val) {
|
|
|
+ throw new IllegalArgumentException("no key exist for update SQL");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 更新数据必须指定条件
|
|
|
+ */
|
|
|
+ private void checkConditionOnUpdate(OBuilder OBuilder) {
|
|
|
+ if (null == OBuilder || DbUtil.isEmptyOrNull(OBuilder.getWheres())) {
|
|
|
+ throw new IllegalArgumentException("no builder condition exist for update SQL");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+//region delete
|
|
|
+
|
|
|
+ /**
|
|
|
+ * ------------delete------------
|
|
|
+ */
|
|
|
+ public final int delete(Class<?> clz, OBuilder OBuilder) {
|
|
|
+ checkConditionOnDelete(OBuilder);
|
|
|
+ beforeDelete(clz, OBuilder);
|
|
|
+ SQLEntity delete = helper.delete(clz, OBuilder);
|
|
|
+ int count = executeUpdate(delete);
|
|
|
+ if (count == 0) {
|
|
|
+ logger.warn("SQLHandler WARN# no record delete,class:{},builder:{}", clz.getSimpleName(), OBuilder);
|
|
|
+ }
|
|
|
+ return count;
|
|
|
+ }
|
|
|
+
|
|
|
+ public final int delete(Class<?> clz, Object id) {
|
|
|
+ if (DbUtil.isEmptyOrNull(id)) {
|
|
|
+ throw new IllegalArgumentException("delete without id exist!");
|
|
|
+ }
|
|
|
+ beforeDelete(clz, id);
|
|
|
+ SQLEntity delete = helper.deleteById(clz, id);
|
|
|
+ int count = executeUpdate(delete);
|
|
|
+ if (count == 0) {
|
|
|
+ logger.warn("SQLHandler WARN# no record delete,class:{},id:{}", clz.getSimpleName(), id);
|
|
|
+ }
|
|
|
+ return count;
|
|
|
+ }
|
|
|
+
|
|
|
+ //endregion
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 检验条件避免truncate表
|
|
|
+ */
|
|
|
+ private void checkConditionOnDelete(OBuilder OBuilder) {
|
|
|
+ if (null == OBuilder || DbUtil.isEmptyOrNull(OBuilder.getWheres())) {
|
|
|
+ throw new IllegalArgumentException("delete without builder condition exist!");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * ---------------util tool----------
|
|
|
+ */
|
|
|
+ public final void setFieldValue(Object bean, String fieldName, Object val) {
|
|
|
+ if (null == val) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ Field field = null;
|
|
|
+ try {
|
|
|
+ try {
|
|
|
+ field = bean.getClass().getDeclaredField(fieldName);
|
|
|
+ } catch (Exception e) {
|
|
|
+ try {
|
|
|
+ field = bean.getClass().getField(fieldName);
|
|
|
+ } catch (Exception e1) {
|
|
|
+ try {
|
|
|
+ field = bean.getClass().getSuperclass().getDeclaredField(fieldName);
|
|
|
+ } catch (Exception e2) {
|
|
|
+ field = bean.getClass().getSuperclass().getField(fieldName);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ field.setAccessible(true);
|
|
|
+ Class<?> type = field.getType();
|
|
|
+ if (type == Date.class) {
|
|
|
+ if (val instanceof String) {
|
|
|
+ //TODO yyyy-mm-dd HH:mm:ss.SSS
|
|
|
+ String v = (String) val;
|
|
|
+ if (v.length() == 10) {
|
|
|
+ LocalDate time = LocalDate.parse(v, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
|
|
|
+ Date d = Date.from(LocalDateTime.of(time, LocalTime.MIN).atZone(ZoneId.systemDefault()).toInstant());
|
|
|
+ field.set(bean, d);
|
|
|
+ } else if (v.length() > 20 && v.length() <= 24) {
|
|
|
+ LocalDateTime time = LocalDateTime.parse(v, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"));
|
|
|
+ Date d = Date.from(time.atZone(ZoneId.systemDefault()).toInstant());
|
|
|
+ field.set(bean, d);
|
|
|
+ } else if (v.length() > 24) {
|
|
|
+ LocalDateTime time = LocalDateTime.parse(v, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSSSSS"));
|
|
|
+ Date d = Date.from(time.atZone(ZoneId.systemDefault()).toInstant());
|
|
|
+ field.set(bean, d);
|
|
|
+ } else {
|
|
|
+ LocalDateTime time = LocalDateTime.parse(v, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
|
|
|
+ Date d = Date.from(time.atZone(ZoneId.systemDefault()).toInstant());
|
|
|
+ field.set(bean, d);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ field.set(bean, val);
|
|
|
+ }
|
|
|
+ } else if (type == String.class) {
|
|
|
+ field.set(bean, val.toString());
|
|
|
+ } else if (type == int.class || type == Integer.class) {
|
|
|
+ //db tinyint(1)->boolean
|
|
|
+ if (val instanceof Boolean) {
|
|
|
+ field.set(bean, (Boolean) val ? 1 : 0);
|
|
|
+ } else {
|
|
|
+ field.set(bean, Integer.valueOf(val.toString()));
|
|
|
+ }
|
|
|
+ } else if (type == double.class || type == Double.class) {
|
|
|
+ field.set(bean, Double.valueOf(val.toString()));
|
|
|
+ } else if (type == long.class || type == Long.class) {
|
|
|
+ field.set(bean, Long.valueOf(val.toString()));
|
|
|
+ } else if (type == float.class || type == Float.class) {
|
|
|
+ field.set(bean, Float.valueOf(val.toString()));
|
|
|
+ } else if (type == short.class || type == Short.class) {
|
|
|
+ field.set(bean, Short.valueOf(val.toString()));
|
|
|
+ } else if (type == byte.class || type == Byte.class) {
|
|
|
+ field.set(bean, Byte.valueOf(val.toString()));
|
|
|
+ } else if (type == boolean.class || type == Boolean.class) {
|
|
|
+ if (val instanceof String) {
|
|
|
+ boolean v = "t".equals(val) || "1".equals(val);
|
|
|
+ field.set(bean, v);
|
|
|
+ } else {
|
|
|
+ field.set(bean, Boolean.valueOf(val.toString()));
|
|
|
+ }
|
|
|
+ } else if (type == char.class || type == Character.class) {
|
|
|
+ field.set(bean, val);
|
|
|
+ } else if (type == BigDecimal.class) {
|
|
|
+ field.set(bean, new BigDecimal(val.toString()));
|
|
|
+ } else if (type.isArray()) {
|
|
|
+ if (DbUtil.isEmptyOrNull(val)) {
|
|
|
+ val = "[]";
|
|
|
+ }
|
|
|
+ setFieldArrayValue(bean, field, type, val.toString());
|
|
|
+ } else if (type.isAssignableFrom(List.class) && !val.getClass().isAssignableFrom(ArrayList.class)) {
|
|
|
+ if (DbUtil.isEmptyOrNull(val)) {
|
|
|
+ val = Collections.emptyList();
|
|
|
+ }
|
|
|
+ Type collClz = ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0];
|
|
|
+ field.set(bean, JacksonUtil.toJavaObjectList(val.toString(), (Class<?>) collClz));
|
|
|
+ } else if (type.isAssignableFrom(Set.class) && !val.getClass().isAssignableFrom(HashSet.class)) {
|
|
|
+ if (DbUtil.isEmptyOrNull(val)) {
|
|
|
+ val = Collections.emptySet();
|
|
|
+ }
|
|
|
+ Type collClz = ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0];
|
|
|
+ List<?> dataList = JacksonUtil.toJavaObjectList(val.toString(), (Class<?>) collClz);
|
|
|
+ if (DbUtil.isEmptyOrNull(dataList)) {
|
|
|
+ field.set(bean, Collections.emptySet());
|
|
|
+ } else {
|
|
|
+ field.set(bean, new HashSet<>(dataList));
|
|
|
+ }
|
|
|
+
|
|
|
+ } else if (type.isAssignableFrom(Map.class)) {
|
|
|
+ if (DbUtil.isEmptyOrNull(val)) {
|
|
|
+ val = new HashMap<>();
|
|
|
+ }
|
|
|
+ field.set(bean, JacksonUtil.toJavaObject(val.toString(), Map.class));
|
|
|
+ } else {
|
|
|
+ logger.debug("setFieldValue>> {},{}", fieldName, bean.getClass().getName());
|
|
|
+ field.set(bean, JacksonUtil.toJavaObject(val.toString(), type));
|
|
|
+// field.set(bean, val);
|
|
|
+ }
|
|
|
+ field.setAccessible(false);
|
|
|
+ } catch (Exception e) {
|
|
|
+ logger.warn("SQLHandler ERR# setFieldValue111 field:{},{},{}", e.getClass().getSimpleName(), fieldName, val);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void setFieldArrayValue(Object bean, Field field, Class<?> clz, String value) {
|
|
|
+
|
|
|
+ try {
|
|
|
+ List<Object> list = JacksonUtil.toList(value);
|
|
|
+ if (null == list) {
|
|
|
+ field.set(bean, Collections.emptyList());
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (clz == String[].class) {
|
|
|
+ String[] arr = new String[list.size()];
|
|
|
+ if (!DbUtil.isEmptyOrNull(list)) {
|
|
|
+ for (int i = 0; i < list.size(); i++) {
|
|
|
+ arr[i] = ((String) list.get(i)).replaceAll("\u0001", "/");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ field.set(bean, arr);
|
|
|
+ } else if (clz == int[].class) {
|
|
|
+ int[] arr = new int[list.size()];
|
|
|
+ if (!DbUtil.isEmptyOrNull(list)) {
|
|
|
+ for (int i = 0; i < list.size(); i++) {
|
|
|
+ arr[i] = (Integer) list.get(i);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ field.set(bean, arr);
|
|
|
+ } else if (clz == short[].class) {
|
|
|
+ short[] arr = new short[list.size()];
|
|
|
+ if (!DbUtil.isEmptyOrNull(list)) {
|
|
|
+ for (int i = 0; i < list.size(); i++) {
|
|
|
+ arr[i] = (Short) list.get(i);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ field.set(bean, arr);
|
|
|
+ } else if (clz == long[].class) {
|
|
|
+ long[] arr = new long[list.size()];
|
|
|
+ if (!DbUtil.isEmptyOrNull(list)) {
|
|
|
+ for (int i = 0; i < list.size(); i++) {
|
|
|
+ arr[i] = (Long) list.get(i);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ field.set(bean, arr);
|
|
|
+ } else if (clz == byte[].class) {
|
|
|
+ byte[] arr = new byte[list.size()];
|
|
|
+ if (!DbUtil.isEmptyOrNull(list)) {
|
|
|
+ for (int i = 0; i < list.size(); i++) {
|
|
|
+ arr[i] = (Byte) list.get(i);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ field.set(bean, arr);
|
|
|
+ } else if (clz == double[].class) {
|
|
|
+ double[] arr = new double[list.size()];
|
|
|
+ if (!DbUtil.isEmptyOrNull(list)) {
|
|
|
+ for (int i = 0; i < list.size(); i++) {
|
|
|
+ arr[i] = (Double) list.get(i);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ field.set(bean, arr);
|
|
|
+ } else if (clz == float[].class) {
|
|
|
+ float[] arr = new float[list.size()];
|
|
|
+ if (!DbUtil.isEmptyOrNull(list)) {
|
|
|
+ for (int i = 0; i < list.size(); i++) {
|
|
|
+ arr[i] = (Float) list.get(i);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ field.set(bean, arr);
|
|
|
+ } else if (clz == char[].class) {
|
|
|
+ char[] arr = new char[list.size()];
|
|
|
+ if (!DbUtil.isEmptyOrNull(list)) {
|
|
|
+ for (int i = 0; i < list.size(); i++) {
|
|
|
+ arr[i] = (Character) list.get(i);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ field.set(bean, arr);
|
|
|
+ } else if (clz == boolean[].class) {
|
|
|
+ boolean[] arr = new boolean[list.size()];
|
|
|
+ if (!DbUtil.isEmptyOrNull(list)) {
|
|
|
+ for (int i = 0; i < list.size(); i++) {
|
|
|
+ arr[i] = (Boolean) list.get(i);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ field.set(bean, arr);
|
|
|
+ } else {
|
|
|
+ Object[] arr = new Object[list.size()];
|
|
|
+ if (!DbUtil.isEmptyOrNull(list)) {
|
|
|
+ for (int i = 0; i < list.size(); i++) {
|
|
|
+ arr[i] = list.get(i);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ field.set(bean, arr);
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ throw new IllegalArgumentException("convert array field ERR");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public final void setFieldValue(Class<?> type, Object bean, String fieldName, Object val) {
|
|
|
+ try {
|
|
|
+ Field field = bean.getClass().getField(fieldName);
|
|
|
+ field.setAccessible(true);
|
|
|
+ if (type == Date.class) {
|
|
|
+ field.set(bean, val);
|
|
|
+ } else if (type == String.class) {
|
|
|
+ field.set(bean, val.toString());
|
|
|
+ } else if (type == int.class || type == Integer.class) {
|
|
|
+ field.set(bean, Integer.valueOf(val.toString()));
|
|
|
+ } else if (type == double.class || type == Double.class) {
|
|
|
+ field.set(bean, Double.valueOf(val.toString()));
|
|
|
+ } else if (type == long.class || type == Long.class) {
|
|
|
+ field.set(bean, Long.valueOf(val.toString()));
|
|
|
+ } else if (type == float.class || type == Float.class) {
|
|
|
+ field.set(bean, Float.valueOf(val.toString()));
|
|
|
+ } else if (type == short.class || type == Short.class) {
|
|
|
+ field.set(bean, Short.valueOf(val.toString()));
|
|
|
+ } else if (type == byte.class || type == Byte.class) {
|
|
|
+ field.set(bean, Byte.valueOf(val.toString()));
|
|
|
+ } else if (type == boolean.class || type == Boolean.class) {
|
|
|
+ field.set(bean, Boolean.valueOf(val.toString()));
|
|
|
+ } else if (type == char.class || type == Character.class) {
|
|
|
+ field.set(bean, val);
|
|
|
+ } else if (field.getType().isArray()) {
|
|
|
+ field.set(bean, JacksonUtil.toList(val.toString()));
|
|
|
+ } else if (type == BigDecimal.class) {
|
|
|
+ field.set(bean, new BigDecimal(val.toString()));
|
|
|
+ }
|
|
|
+ field.setAccessible(false);
|
|
|
+ } catch (Exception e) {
|
|
|
+ logger.error("SQLHandler ERR# setFieldValue " + e.getMessage(), e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public final Object getFieldValue(Object bean, String fieldName) {
|
|
|
+ Object defValu = "";
|
|
|
+ try {
|
|
|
+ fieldName = getCamelName(fieldName);
|
|
|
+// Field field = bean.getClass().getField(fieldName);
|
|
|
+ Field field = DbUtil.getField(bean, fieldName);
|
|
|
+ field.setAccessible(true);
|
|
|
+ defValu = field.get(bean);
|
|
|
+ if (null == defValu) {
|
|
|
+ Class<?> type = field.getType();
|
|
|
+ if (type == String.class) {
|
|
|
+ defValu = "";
|
|
|
+ } else if (type == int.class || type == Integer.class) {
|
|
|
+ defValu = 0;
|
|
|
+ } else if (type == double.class || type == Double.class) {
|
|
|
+ defValu = 0d;
|
|
|
+ } else if (type == long.class || type == Long.class) {
|
|
|
+ defValu = 0L;
|
|
|
+ } else if (type == float.class || type == Float.class) {
|
|
|
+ defValu = 0F;
|
|
|
+ } else if (type == short.class || type == Short.class) {
|
|
|
+ defValu = 0;
|
|
|
+ } else if (type == byte.class || type == Byte.class) {
|
|
|
+ defValu = 0;
|
|
|
+ } else if (type == boolean.class || type == Boolean.class) {
|
|
|
+ defValu = 0;
|
|
|
+ } else if (type == char.class || type == Character.class) {
|
|
|
+ defValu = '0';
|
|
|
+ } else if (field.getType().isArray()) {
|
|
|
+ defValu = new Object[]{};
|
|
|
+ }
|
|
|
+ }
|
|
|
+ field.setAccessible(false);
|
|
|
+ } catch (Exception e) {
|
|
|
+ logger.warn("SQLHandler ERR# getFieldValue ,field:{}, bean:{} ,msg:{}", fieldName, bean.getClass().getSimpleName(), e.getMessage());
|
|
|
+ }
|
|
|
+ return defValu;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ protected final String getColumnName(String fieldName) {
|
|
|
+ StringBuilder sbr = new StringBuilder();
|
|
|
+ char[] chars = fieldName.toCharArray();
|
|
|
+ for (char ch : chars) {
|
|
|
+ if (Character.isUpperCase(ch)) {
|
|
|
+ sbr.append("_").append(Character.toLowerCase(ch));
|
|
|
+ } else {
|
|
|
+ sbr.append(ch);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return sbr.toString();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取驼峰变量名
|
|
|
+ */
|
|
|
+ protected final String getCamelName(String fieldName) {
|
|
|
+ StringBuilder sbr = new StringBuilder();
|
|
|
+ char[] chars = fieldName.toCharArray();
|
|
|
+ boolean preUpper = false;
|
|
|
+ for (char ch : chars) {
|
|
|
+ if ('_' == ch) {
|
|
|
+ preUpper = true;
|
|
|
+ } else {
|
|
|
+ if (preUpper) {
|
|
|
+ sbr.append(Character.toUpperCase(ch));
|
|
|
+ preUpper = false;
|
|
|
+ } else {
|
|
|
+ sbr.append(ch);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return sbr.toString();
|
|
|
+ }
|
|
|
+
|
|
|
+ protected final String getTableName(String tbName) {
|
|
|
+ if (tbName.endsWith("Info")) {
|
|
|
+ tbName = tbName.substring(0, tbName.length() - 4);
|
|
|
+ }
|
|
|
+ return JdbcHelper.getTbPrefix() + getColumnName(tbName);
|
|
|
+ }
|
|
|
+
|
|
|
+ private <T> T map2Object(Class<T> clz, ResultSet rs) throws SQLException {
|
|
|
+ Map<String, Object> map = new HashMap<>(16);
|
|
|
+ ResultSetMetaData metaData = rs.getMetaData();
|
|
|
+ int count = metaData.getColumnCount();
|
|
|
+ List<String> dbFields = new ArrayList<>();
|
|
|
+ for (int i = 1; i < count + 1; i++) {
|
|
|
+ dbFields.add(metaData.getColumnLabel(i));
|
|
|
+ }
|
|
|
+ for (String dbField : dbFields) {
|
|
|
+ map.put(dbField, rs.getString(dbField));
|
|
|
+ }
|
|
|
+ if (clz.isAssignableFrom(Map.class)) {
|
|
|
+ return (T) map;
|
|
|
+ }
|
|
|
+ return map2Object(clz, map);
|
|
|
+ }
|
|
|
+
|
|
|
+ private <T> T map2Object(Class<T> clz, Map<String, Object> map) {
|
|
|
+ if (DbUtil.isEmptyOrNull(map)) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ Set<Field> fields = DbUtil.getEntityFields(clz);
|
|
|
+ try {
|
|
|
+ Map<String, Class<?>> join = new HashMap<>(2);
|
|
|
+ T t = clz.newInstance();
|
|
|
+ Map<String, Field> fieldMap = new HashMap<>();
|
|
|
+ for (Field field : fields) {
|
|
|
+ if (DbUtil.isUsageField(field)) {
|
|
|
+ String fieldName = field.getName();
|
|
|
+ Class<?> type = field.getType();
|
|
|
+ if (!type.isArray() && type != List.class && type != Set.class && !DbUtil.isGenericType(type) && type != String.class && type != Date.class && type != BigDecimal.class && type != Map.class && !field.isAnnotationPresent(DBF.class)) {
|
|
|
+ join.put(fieldName, type);
|
|
|
+ fieldMap.put(fieldName, field);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ Object val = map.get(getColumnName(fieldName));
|
|
|
+ if (null == val) {
|
|
|
+ if (type.isArray()) {
|
|
|
+ //类型转换
|
|
|
+ setFieldValue(t, fieldName, new Object[]{});
|
|
|
+ } else if (type.isAssignableFrom(List.class)) {
|
|
|
+ setFieldValue(t, fieldName, Collections.emptyList());
|
|
|
+ } else if (type.isAssignableFrom(Set.class)) {
|
|
|
+ setFieldValue(t, fieldName, Collections.emptySet());
|
|
|
+ } else if (type.isAssignableFrom(Map.class)) {
|
|
|
+ setFieldValue(t, fieldName, Collections.emptyMap());
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ setFieldValue(t, fieldName, val);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //关联类型
|
|
|
+ if (!DbUtil.isEmptyOrNull(join)) {
|
|
|
+ join.forEach((fieldName, clzType) -> {
|
|
|
+ //java field => Account account
|
|
|
+ //sql field =>account_id,account_name
|
|
|
+ try {
|
|
|
+ Field field = fieldMap.get(fieldName);
|
|
|
+ One one = field.getAnnotation(One.class);
|
|
|
+ if (null != one && !one.noQuery() && !DbUtil.isGenericType(clzType)) {
|
|
|
+ String prefix = field.getName();
|
|
|
+ Object o = field.getType().newInstance();
|
|
|
+ Set<Field> oneFields = DbUtil.getEntityFields(field.getType());
|
|
|
+// Field[] oneFields = field.getType().getFields();
|
|
|
+ boolean oneSet = false;
|
|
|
+ for (Field oneField : oneFields) {
|
|
|
+ if (oneField.isAnnotationPresent(DBF.class)) {
|
|
|
+ String oneKey = prefix + "_" + getColumnName(oneField.getName());
|
|
|
+ Object oneValue = map.get(oneKey);
|
|
|
+ if (null == oneValue) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ setFieldValue(o, oneField.getName(), oneValue);
|
|
|
+ oneSet = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (oneSet) {
|
|
|
+ setFieldValue(t, field.getName(), o);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!DbUtil.isEmptyOrNull(map.get(fieldName))) {
|
|
|
+ Object joinObj = JacksonUtil.toJavaObject(map.get(fieldName).toString(), clzType);
|
|
|
+ setFieldValue(t, fieldName, joinObj);
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ logger.error("SQLHandler ERR# deal with db join reuslt by map2object,field:" + fieldName, e);
|
|
|
+ }
|
|
|
+
|
|
|
+ });
|
|
|
+ }
|
|
|
+ return t;
|
|
|
+ } catch (InstantiationException | IllegalAccessException e) {
|
|
|
+ logger.error("SQLHandler ERR# deal with db reuslt by map2object", e);
|
|
|
+ throw new IllegalStateException(e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private <T> List<T> map2ObjectList(Class<T> clz, List<Map<String, Object>> list) {
|
|
|
+ List<T> retList = new ArrayList<>(list.size());
|
|
|
+ if (!DbUtil.isEmptyOrNull(list)) {
|
|
|
+ list.forEach(map -> {
|
|
|
+ T t = map2Object(clz, map);
|
|
|
+ if (null != t) {
|
|
|
+ retList.add(t);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ return retList;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 关联集合查询并赋值
|
|
|
+ * 优化方案:一对多可以在联表查询时一并带出,不必进行二次查询
|
|
|
+ */
|
|
|
+ private void setJoinList(Object t, Class<?> clz, List<String> exclude) {
|
|
|
+ Field[] fields = clz.getDeclaredFields();
|
|
|
+ for (Field field : fields) {
|
|
|
+ if (field.isAnnotationPresent(Many.class) && !field.getAnnotation(Many.class).noQuery()) {
|
|
|
+ String fieldName = field.getName();
|
|
|
+ if (!DbUtil.isEmptyOrNull(exclude) && exclude.contains(fieldName)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ Many manyAnnotation = field.getAnnotation(Many.class);
|
|
|
+ String fkField = manyAnnotation.mkf();
|
|
|
+ Object value = getFieldValue(t, fkField);
|
|
|
+ List<?> list = selectList(manyAnnotation.te(), OBuilder.build().eq(manyAnnotation.tkf(), value));
|
|
|
+ setFieldValue(t, fieldName, list);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String getHandlerType() {
|
|
|
+ return IHandler.JDBC;
|
|
|
+ }
|
|
|
+}
|