Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.tairanchina.csp.dew.jdbc.DewDS Maven / Gradle / Ivy
package com.tairanchina.csp.dew.jdbc;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLObjectImpl;
import com.alibaba.druid.sql.ast.expr.*;
import com.alibaba.druid.sql.ast.statement.*;
import com.alibaba.druid.sql.dialect.db2.parser.DB2StatementParser;
import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser;
import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser;
import com.alibaba.druid.sql.dialect.phoenix.parser.PhoenixStatementParser;
import com.alibaba.druid.sql.dialect.postgresql.parser.PGSQLStatementParser;
import com.alibaba.druid.sql.dialect.sqlserver.parser.SQLServerStatementParser;
import com.alibaba.druid.sql.parser.SQLStatementParser;
import com.ecfront.dew.common.$;
import com.ecfront.dew.common.Page;
import com.ecfront.dew.common.StandardCode;
import com.tairanchina.csp.dew.Dew;
import com.tairanchina.csp.dew.core.jdbc.DS;
import com.tairanchina.csp.dew.core.jdbc.SB;
import com.tairanchina.csp.dew.jdbc.dialect.Dialect;
import com.tairanchina.csp.dew.jdbc.dialect.DialectFactory;
import com.tairanchina.csp.dew.jdbc.dialect.DialectType;
import com.tairanchina.csp.dew.jdbc.entity.EntityContainer;
import com.tairanchina.csp.dew.jdbc.proxy.MethodConstruction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.IncorrectResultSizeDataAccessException;
import org.springframework.jdbc.core.ArgumentPreparedStatementSetter;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementSetter;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import java.sql.PreparedStatement;
import java.sql.Time;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
public class DewDS implements DS {
private static final Logger logger = LoggerFactory.getLogger(DewDS.class);
private static final Pattern FIELD_PLACE_HOLDER_PATTERN = Pattern.compile("\\#\\{\\s*\\w+\\s*\\}"); // 正则匹配 #{key}
private static final char UNDERLINE = '_';
private static final String STAR = "*";
private static final String POINT = "";
private static final String EMPTY = "";
private String leftDecorated;
private String rightDecorated;
private JdbcTemplate jdbcTemplate;
private String jdbcUrl;
private Dialect dialect;
private void init() {
dialect = DialectFactory.parseDialect(jdbcUrl);
switch (dialect.getDialectType()) {
case H2:
leftDecorated = "`";
rightDecorated = "`";
break;
case MYSQL:
leftDecorated = "`";
rightDecorated = "`";
break;
case ORACLE:
leftDecorated = "\"";
rightDecorated = "\"";
break;
case POSTGRE:
leftDecorated = "\"";
rightDecorated = "\"";
break;
case SQLSERVER:
leftDecorated = "[";
rightDecorated = "]";
break;
case DB2:
leftDecorated = "[";
rightDecorated = "]";
break;
case PHOENIX:
leftDecorated = "[";
rightDecorated = "]";
break;
default:
break;
}
}
public JdbcTemplate jdbc() {
return jdbcTemplate;
}
@Override
public Object insert(Object entity) {
EntityContainer.EntityClassInfo entityClassInfo = EntityContainer.getEntityClassByClazz(entity.getClass());
Object[] packageInsert = packageInsert(new ArrayList() {{
add(entity);
}}, true);
String sql = (String) packageInsert[0];
Object[] args = ((List) packageInsert[1]).get(0);
if (entityClassInfo.pkFieldNameOpt.isPresent() &&
entityClassInfo.pkUUIDOpt.isPresent() && entityClassInfo.pkUUIDOpt.get()) {
jdbcTemplate.update(sql, args);
return ((Optional) packageInsert[2]).get();
} else if (entityClassInfo.pkFieldNameOpt.isPresent()) {
KeyHolder keyHolder = new GeneratedKeyHolder();
jdbcTemplate.update(con -> {
PreparedStatement ps = con.prepareStatement(sql, new String[]{entityClassInfo.pkFieldNameOpt.get()});
PreparedStatementSetter pss = new ArgumentPreparedStatementSetter(args);
pss.setValues(ps);
return ps;
}, keyHolder);
return keyHolder.getKey();
} else {
jdbcTemplate.update(sql, args);
return 0;
}
}
@Override
public void insert(Iterable> entities) {
Object[] packageInsert = packageInsert(entities, false);
jdbcTemplate.batchUpdate((String) packageInsert[0], (List) packageInsert[1]);
}
@Override
public int updateById(Object id, Object entity) {
try {
$.bean.setValue(entity, EntityContainer.getEntityClassByClazz(entity.getClass()).pkFieldNameOpt.get(), id);
Object[] packageUpdate = packageUpdate(entity, true);
return jdbcTemplate.update((String) packageUpdate[0], (Object[]) packageUpdate[1]);
} catch (NoSuchFieldException e) {
logger.error("UpdateById error", e);
return 0;
}
}
@Override
public int updateByCode(String code, Object entity) {
try {
$.bean.setValue(entity, EntityContainer.getEntityClassByClazz(entity.getClass()).codeFieldNameOpt.get(), code);
Object[] packageUpdate = packageUpdate(entity, true);
return jdbcTemplate.update((String) packageUpdate[0], (Object[]) packageUpdate[1]);
} catch (NoSuchFieldException e) {
logger.error("updateByCode error", e);
return 0;
}
}
@Override
public E getById(Object id, Class entityClazz) {
EntityContainer.EntityClassInfo entityClassInfo = EntityContainer.getEntityClassByClazz(entityClazz);
return get(DewSB.inst()
.eq(entityClassInfo.pkFieldNameOpt.get(), id), entityClazz);
}
@Override
public E getByCode(String code, Class entityClazz) {
EntityContainer.EntityClassInfo entityClassInfo = EntityContainer.getEntityClassByClazz(entityClazz);
return get(DewSB.inst()
.eq(entityClassInfo.codeFieldNameOpt.get(), code), entityClazz);
}
@Override
public E get(SB sqlBuilder, Class entityClazz) {
Object[] packageSelect = packageSelect(entityClazz, sqlBuilder);
return get((String) packageSelect[0], (Object[]) packageSelect[1], entityClazz);
}
@Override
public E get(String sql, Object[] params, Class entityClazz) {
List> result = jdbcTemplate.queryForList(sql, (Object[]) params);
if (result.size() == 1) {
return convertRsToObj(result.get(0), entityClazz);
} else if (result.isEmpty()) {
return null;
} else {
throw new IncorrectResultSizeDataAccessException(1);
}
}
@Override
public int deleteById(Object id, Class> entityClazz) {
EntityContainer.EntityClassInfo entityClassInfo = EntityContainer.getEntityClassByClazz(entityClazz);
return delete(DewSB.inst()
.eq(entityClassInfo.pkFieldNameOpt.get(), id), entityClazz);
}
@Override
public int deleteByCode(String code, Class> entityClazz) {
EntityContainer.EntityClassInfo entityClassInfo = EntityContainer.getEntityClassByClazz(entityClazz);
return delete(DewSB.inst()
.eq(entityClassInfo.codeFieldNameOpt.get(), code), entityClazz);
}
@Override
public int deleteAll(Class> entityClazz) {
return delete(DewSB.inst(), entityClazz);
}
@Override
public int delete(SB sqlBuilder, Class> entityClazz) {
EntityContainer.EntityClassInfo entityClassInfo = EntityContainer.getEntityClassByClazz(entityClazz);
Object[] sb = ((DewSB) sqlBuilder).build(entityClassInfo, leftDecorated, rightDecorated);
return jdbcTemplate.update(String.format("DELETE FROM " + leftDecorated + "%s" + rightDecorated + " %s",
entityClassInfo.tableName, sb[0]),
((List) sb[1]).toArray());
}
@Override
public int enableById(Object id, Class> entityClazz) {
EntityContainer.EntityClassInfo entityClassInfo = EntityContainer.getEntityClassByClazz(entityClazz);
return enable(DewSB.inst()
.eq(entityClassInfo.pkFieldNameOpt.get(), id), entityClazz);
}
@Override
public int enableByCode(String code, Class> entityClazz) {
EntityContainer.EntityClassInfo entityClassInfo = EntityContainer.getEntityClassByClazz(entityClazz);
return enable(DewSB.inst().eq(entityClassInfo.codeFieldNameOpt.get(), code), entityClazz);
}
@Override
public int enable(SB sqlBuilder, Class> entityClazz) {
EntityContainer.EntityClassInfo entityClassInfo = EntityContainer.getEntityClassByClazz(entityClazz);
Object[] sb = ((DewSB) sqlBuilder).build(entityClassInfo, leftDecorated, rightDecorated);
EntityContainer.EntityClassInfo.Column column = entityClassInfo.columns.get(entityClassInfo.enabledFieldNameOpt.get());
((List) sb[1]).add(0, !column.reverse);
return jdbcTemplate.update(String.format("UPDATE %s SET " + leftDecorated + "%s" + rightDecorated + " = ? %s",
entityClassInfo.tableName,
column.columnName,
sb[0]),
((List) sb[1]).toArray());
}
@Override
public int disableById(Object id, Class> entityClazz) {
EntityContainer.EntityClassInfo entityClassInfo = EntityContainer.getEntityClassByClazz(entityClazz);
return disable(DewSB.inst()
.eq(entityClassInfo.pkFieldNameOpt.get(), id), entityClazz);
}
@Override
public int disableByCode(String code, Class> entityClazz) {
EntityContainer.EntityClassInfo entityClassInfo = EntityContainer.getEntityClassByClazz(entityClazz);
return disable(DewSB.inst()
.eq(entityClassInfo.codeFieldNameOpt.get(), code), entityClazz);
}
@Override
public int disable(SB sqlBuilder, Class> entityClazz) {
EntityContainer.EntityClassInfo entityClassInfo = EntityContainer.getEntityClassByClazz(entityClazz);
Object[] sb = ((DewSB) sqlBuilder).build(entityClassInfo, leftDecorated, rightDecorated);
EntityContainer.EntityClassInfo.Column column = entityClassInfo.columns.get(entityClassInfo.enabledFieldNameOpt.get());
((List) sb[1]).add(0, column.reverse);
return jdbcTemplate.update(String.format("UPDATE %s SET " + leftDecorated + "%s" + rightDecorated + " = ? %s",
entityClassInfo.tableName,
column.columnName,
sb[0]),
((List) sb[1]).toArray());
}
@Override
public int update(String sql, Object[] params) {
return jdbcTemplate.update(sql, params);
}
@Override
public boolean existById(Object id, Class> entityClazz) {
EntityContainer.EntityClassInfo entityClassInfo = EntityContainer.getEntityClassByClazz(entityClazz);
return exist(DewSB.inst()
.eq(entityClassInfo.pkFieldNameOpt.get(), id), entityClazz);
}
@Override
public boolean existByCode(String code, Class> entityClazz) {
EntityContainer.EntityClassInfo entityClassInfo = EntityContainer.getEntityClassByClazz(entityClazz);
return exist(DewSB.inst()
.eq(entityClassInfo.codeFieldNameOpt.get(), code), entityClazz);
}
@Override
public boolean exist(SB sqlBuilder, Class> entityClazz) {
EntityContainer.EntityClassInfo entityClassInfo = EntityContainer.getEntityClassByClazz(entityClazz);
Object[] sb = ((DewSB) sqlBuilder).build(entityClassInfo, leftDecorated, rightDecorated);
return exist(String.format("SELECT 1 FROM " + leftDecorated + "%s" + rightDecorated + " %s",
entityClassInfo.tableName,
sb[0]),
((List) sb[1]).toArray());
}
@Override
public boolean exist(String sql, Object[] params) {
return jdbcTemplate.queryForObject(dialect.count(sql), params, Long.class) != 0;
}
@Override
public List findAll(Class entityClazz) {
return find(DewSB.inst(), entityClazz);
}
@Override
public List findEnabled(Class entityClazz) {
EntityContainer.EntityClassInfo entityClassInfo = EntityContainer.getEntityClassByClazz(entityClazz);
return find(DewSB.inst().eq(entityClassInfo.enabledFieldNameOpt.get(), true), entityClazz);
}
@Override
public List findDisabled(Class entityClazz) {
EntityContainer.EntityClassInfo entityClassInfo = EntityContainer.getEntityClassByClazz(entityClazz);
return find(DewSB.inst().eq(entityClassInfo.enabledFieldNameOpt.get(), false), entityClazz);
}
@Override
public List find(SB sqlBuilder, Class entityClazz) {
Object[] packageSelect = packageSelect(entityClazz, sqlBuilder);
return find((String) packageSelect[0], (Object[]) packageSelect[1], entityClazz);
}
@Override
public List find(String sql, Object[] params, Class entityClazz) {
return jdbcTemplate.queryForList(sql, params).stream()
.map(row -> convertRsToObj(row, entityClazz))
.collect(Collectors.toList());
}
@Override
public long countAll(Class> entityClazz) {
return count(DewSB.inst(), entityClazz);
}
@Override
public long countEnabled(Class> entityClazz) {
EntityContainer.EntityClassInfo entityClassInfo = EntityContainer.getEntityClassByClazz(entityClazz);
EntityContainer.EntityClassInfo.Column column = entityClassInfo.columns.get(entityClassInfo.enabledFieldNameOpt.get());
return count(DewSB.inst()
.eq(entityClassInfo.enabledFieldNameOpt.get(), !column.reverse), entityClazz);
}
@Override
public long countDisabled(Class> entityClazz) {
EntityContainer.EntityClassInfo entityClassInfo = EntityContainer.getEntityClassByClazz(entityClazz);
EntityContainer.EntityClassInfo.Column column = entityClassInfo.columns.get(entityClassInfo.enabledFieldNameOpt.get());
return count(DewSB.inst()
.eq(entityClassInfo.enabledFieldNameOpt.get(), column.reverse), entityClazz);
}
@Override
public long count(SB sqlBuilder, Class> entityClazz) {
EntityContainer.EntityClassInfo entityClassInfo = EntityContainer.getEntityClassByClazz(entityClazz);
Object[] sb = ((DewSB) sqlBuilder).build(entityClassInfo, leftDecorated, rightDecorated);
return count(String.format("SELECT 1 FROM " + leftDecorated + "%s" + rightDecorated + " %s",
entityClassInfo.tableName,
sb[0]),
((List) sb[1]).toArray());
}
@Override
public long count(String sql, Object[] params) {
return jdbcTemplate.queryForObject(dialect.count(sql), params, Long.class);
}
@Override
public Page paging(long pageNumber, int pageSize, Class entityClazz) {
return paging(DewSB.inst(), pageNumber, pageSize, entityClazz);
}
@Override
public Page pagingEnabled(long pageNumber, int pageSize, Class entityClazz) {
EntityContainer.EntityClassInfo entityClassInfo = EntityContainer.getEntityClassByClazz(entityClazz);
return paging(DewSB.inst()
.eq(entityClassInfo.enabledFieldNameOpt.get(), true), pageNumber, pageSize, entityClazz);
}
@Override
public Page pagingDisabled(long pageNumber, int pageSize, Class entityClazz) {
EntityContainer.EntityClassInfo entityClassInfo = EntityContainer.getEntityClassByClazz(entityClazz);
return paging(DewSB.inst()
.eq(entityClassInfo.enabledFieldNameOpt.get(), false), pageNumber, pageSize, entityClazz);
}
@Override
public Page paging(SB sqlBuilder, long pageNumber, int pageSize, Class entityClazz) {
Object[] packageSelect = packageSelect(entityClazz, sqlBuilder);
return paging((String) packageSelect[0], (Object[]) packageSelect[1], pageNumber, pageSize, entityClazz);
}
@Override
public Page paging(String sql, Object[] params, long pageNumber, int pageSize, Class entityClazz) {
String countSql = wrapCountSql(sql);
String pagedSql = wrapPagingSql(sql, pageNumber, pageSize);
long totalRecords = jdbcTemplate.queryForObject(countSql, params, Long.class);
List objects = jdbcTemplate.queryForList(pagedSql, params).stream()
.map(row -> convertRsToObj(row, entityClazz))
.collect(Collectors.toList());
return Page.build(pageNumber, pageSize, totalRecords, objects);
}
public String wrapPagingSql(String oriSql, long pageNumber, int pageSize) {
return dialect.paging(oriSql, pageNumber, pageSize);
}
public String wrapCountSql(String oriSql) {
return dialect.count(oriSql);
}
/**
* 组装插入SQL
*
* @param entities 实体集合
* @return 格式 Object[]{Sql:String,params:List,id:UUID}
*/
private Object[] packageInsert(Iterable> entities, boolean ignoreNullValue) {
if (!entities.iterator().hasNext()) {
throw Dew.E.e(StandardCode.BAD_REQUEST.toString(), new RuntimeException("Entity List is empty."));
}
EntityContainer.EntityClassInfo entityClassInfo = EntityContainer.getEntityClassByClazz(entities.iterator().next().getClass());
String sql = null;
Optional lastIdOpt = Optional.empty();
List params = new ArrayList<>();
for (Object entity : entities) {
Map values = $.bean.findValues(entity, null, null, entityClassInfo.columns.keySet(), null);
if (entityClassInfo.pkFieldNameOpt.isPresent() && entityClassInfo.pkUUIDOpt.get()) {
if (!values.containsKey(entityClassInfo.pkFieldNameOpt.get()) ||
values.get(entityClassInfo.pkFieldNameOpt.get()) == null ||
values.get(entityClassInfo.pkFieldNameOpt.get()).toString().isEmpty()) {
lastIdOpt = Optional.of($.field.createUUID());
values.put(entityClassInfo.pkFieldNameOpt.get(), lastIdOpt.get());
} else {
lastIdOpt = Optional.of(values.get(entityClassInfo.pkFieldNameOpt.get()).toString());
}
} else if (entityClassInfo.pkFieldNameOpt.isPresent() &&
values.containsKey(entityClassInfo.pkFieldNameOpt.get())) {
Object id = values.get(entityClassInfo.pkFieldNameOpt.get());
if (id == null || id instanceof Number && ((Number) id).longValue() == 0) {
// Remove private key field
values.remove(entityClassInfo.pkFieldNameOpt.get());
}
}
// Add ext values
if (entityClassInfo.codeFieldNameOpt.isPresent() && entityClassInfo.codeUUIDOpt.get() &&
(!values.containsKey(entityClassInfo.codeFieldNameOpt.get()) ||
values.get(entityClassInfo.codeFieldNameOpt.get()) == null ||
values.get(entityClassInfo.codeFieldNameOpt.get()).toString().isEmpty())) {
values.put(entityClassInfo.codeFieldNameOpt.get(), $.field.createUUID());
}
LocalDateTime now = LocalDateTime.now();
if (entityClassInfo.createUserFieldNameOpt.isPresent()) {
if (Dew.context().optInfo().isPresent()) {
values.put(entityClassInfo.createUserFieldNameOpt.get(), Dew.context().optInfo().get().getAccountCode());
} else {
values.put(entityClassInfo.createUserFieldNameOpt.get(), EMPTY);
}
}
if (entityClassInfo.createTimeFieldNameOpt.isPresent()) {
values.put(entityClassInfo.createTimeFieldNameOpt.get(), now);
}
if (entityClassInfo.updateUserFieldNameOpt.isPresent()) {
if (Dew.context().optInfo().isPresent()) {
values.put(entityClassInfo.updateUserFieldNameOpt.get(), Dew.context().optInfo().get().getAccountCode());
} else {
values.put(entityClassInfo.updateUserFieldNameOpt.get(), EMPTY);
}
}
if (entityClassInfo.updateTimeFieldNameOpt.isPresent()) {
values.put(entityClassInfo.updateTimeFieldNameOpt.get(), now);
}
// Check null
if (values.entrySet().stream()
.anyMatch(entry -> entityClassInfo.columns.get(entry.getKey()).notNull && entry.getValue() == null)) {
throw Dew.E.e(StandardCode.BAD_REQUEST.toString(), new RuntimeException("Not Null check fail."));
}
// Filter null value if ignoreNullValue=true
if (ignoreNullValue) {
values = values.entrySet().stream()
.filter(entry -> entry.getValue() != null).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}
if (sql == null) {
// Package
StringBuilder sb = new StringBuilder();
sb.append("INSERT INTO ").append(leftDecorated + entityClassInfo.tableName + rightDecorated);
sb.append(values.entrySet().stream()
.map(entry -> leftDecorated + entityClassInfo.columns.get(entry.getKey()).columnName + rightDecorated)
.collect(Collectors.joining(", ", " (", ") ")));
sb.append("VALUES");
sb.append(values.keySet().stream().map(o -> "?").collect(Collectors.joining(", ", " (", ") ")));
sql = sb.toString();
}
params.add(values.values().toArray());
}
return new Object[]{sql, params, lastIdOpt};
}
/**
* 根据主键或Code组装更新SQL
* 存在主键值时使用主键,否则使用Code,都不存在时报错
*
* @param entity 实体
* @param ignoreNullValue 是否忽略null值插入
* @return 格式 Object[]{Sql:String,params:Object[]}
*/
private Object[] packageUpdate(Object entity, boolean ignoreNullValue) {
EntityContainer.EntityClassInfo entityClassInfo = EntityContainer.getEntityClassByClazz(entity.getClass());
Map values = $.bean.findValues(entity, null, null, entityClassInfo.columns.keySet(), null);
// Check id or code Not empty
if (!entityClassInfo.pkFieldNameOpt.isPresent() && !entityClassInfo.codeFieldNameOpt.isPresent()) {
throw Dew.E.e(StandardCode.NOT_FOUND.toString(), new RuntimeException("Need @PkColumn or @CodeColumn field."));
}
String whereColumnName = null;
Object whereValue = null;
if (entityClassInfo.pkFieldNameOpt.isPresent()
&& values.get(entityClassInfo.pkFieldNameOpt.get()) != null
&& !values.get(entityClassInfo.pkFieldNameOpt.get()).toString().isEmpty()) {
if (!"0".equals(values.get(entityClassInfo.pkFieldNameOpt.get()).toString())) {
whereColumnName = entityClassInfo.columns.get(entityClassInfo.pkFieldNameOpt.get()).columnName;
whereValue = values.get(entityClassInfo.pkFieldNameOpt.get());
}
values.remove(entityClassInfo.pkFieldNameOpt.get());
}
if (whereColumnName == null) {
if (entityClassInfo.codeFieldNameOpt.isPresent()
&& values.get(entityClassInfo.codeFieldNameOpt.get()) != null
&& !values.get(entityClassInfo.codeFieldNameOpt.get()).toString().isEmpty()) {
whereColumnName = entityClassInfo.columns.get(entityClassInfo.codeFieldNameOpt.get()).columnName;
whereValue = values.get(entityClassInfo.codeFieldNameOpt.get());
values.remove(entityClassInfo.codeFieldNameOpt.get());
} else {
throw Dew.E.e(StandardCode.BAD_REQUEST.toString(), new RuntimeException("Need Private Key or Code value."));
}
}
// Filter null value if ignoreNullValue=true
if (ignoreNullValue) {
values = values.entrySet().stream()
.filter(entry -> entry.getValue() != null).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}
// Add ext values
if (entityClassInfo.updateUserFieldNameOpt.isPresent()) {
if (Dew.context().optInfo().isPresent()) {
values.put(entityClassInfo.updateUserFieldNameOpt.get(), Dew.context().optInfo().get().getAccountCode());
} else {
values.put(entityClassInfo.updateUserFieldNameOpt.get(), EMPTY);
}
}
if (entityClassInfo.createUserFieldNameOpt.isPresent()) {
values.remove(entityClassInfo.createUserFieldNameOpt.get());
}
if (entityClassInfo.updateTimeFieldNameOpt.isPresent()) {
values.put(entityClassInfo.updateTimeFieldNameOpt.get(), LocalDateTime.now());
}
if (entityClassInfo.createTimeFieldNameOpt.isPresent()) {
values.remove(entityClassInfo.createTimeFieldNameOpt.get());
}
// Check null
if (values.entrySet().stream()
.anyMatch(entry -> entityClassInfo.columns.get(entry.getKey()).notNull && entry.getValue() == null)) {
throw Dew.E.e(StandardCode.BAD_REQUEST.toString(), new RuntimeException("Not Null check fail."));
}
// Package
StringBuilder sb = new StringBuilder();
List params = new ArrayList<>();
sb.append("UPDATE ").append(leftDecorated + entityClassInfo.tableName + rightDecorated).append(" SET ");
sb.append(values.entrySet().stream()
.map(entry -> {
params.add(entry.getValue());
return leftDecorated + entityClassInfo.columns.get(entry.getKey()).columnName + "` = ?";
})
.collect(Collectors.joining(", ")));
sb.append(String.format(" WHERE " + leftDecorated + "%s" + rightDecorated + " = ?", whereColumnName));
params.add(whereValue);
return new Object[]{sb.toString(), params.toArray()};
}
/**
* 组装查询SQL
*
* @param entityClazz 实体类型
* @param sqlBuilder SQL构造器
* @return 格式 Object[]{Sql:String,params:Object[]}
*/
private Object[] packageSelect(Class> entityClazz, SB sqlBuilder) {
EntityContainer.EntityClassInfo entityClassInfo = EntityContainer.getEntityClassByClazz(entityClazz);
StringBuilder sql = new StringBuilder();
Object[] params = new Object[]{};
sql.append("SELECT ");
sql.append(entityClassInfo.columns.values().stream()
.map(col -> leftDecorated + col.columnName + rightDecorated).collect(Collectors.joining(", ")));
sql.append(" FROM ").append(leftDecorated + entityClassInfo.tableName + rightDecorated);
if (sqlBuilder != null) {
Object[] sb = ((DewSB) sqlBuilder).build(entityClassInfo, leftDecorated, rightDecorated);
sql.append(sb[0]);
params = ((List) sb[1]).toArray();
}
return new Object[]{sql.toString(), params};
}
/**
* 将ResultSet转成对象
*
* @param rs ResultSet(Map格式)
* @param entityClazz 对象类型
* @return 转换后的对象
*/
public E convertRsToObj(Map rs, Class entityClazz) {
EntityContainer.EntityClassInfo entityClassInfo = EntityContainer.getEntityClassByClazz(entityClazz);
try {
if ((entityClazz == String.class
|| entityClazz == Integer.class
|| entityClazz == int.class
|| entityClazz == long.class
|| entityClazz == Long.class
|| entityClazz == float.class
|| entityClazz == Float.class
|| entityClazz == double.class
|| entityClazz == Double.class
|| entityClazz == short.class
|| entityClazz == Short.class
|| entityClazz == char.class
|| entityClazz == Character.class) && rs.size() == 1) {
return (E) rs.values().iterator().next();
}
E entity = entityClazz.newInstance();
if (entityClassInfo == null) {
Set fields = $.bean.getFields(entityClazz).keySet();
for (Map.Entry entry : rs.entrySet()) {
String key = underlineToCamel(entry.getKey().toLowerCase());
if (fields.contains(key)) {
Object r = convertRsToObject(entry);
$.bean.setValue(entity, key, r);
}
}
} else {
for (Map.Entry entry : rs.entrySet()) {
if (entityClassInfo.columnRel.containsKey(entry.getKey().toLowerCase())) {
Object r = convertRsToObject(entry);
$.bean.setValue(entity, entityClassInfo.columnRel.get(entry.getKey().toLowerCase()), r);
}
}
}
return entity;
} catch (InstantiationException | IllegalAccessException | NoSuchFieldException | IllegalArgumentException e) {
logger.error("Convert ResultSet to Object error", e);
return null;
}
}
private Object convertRsToObject(Map.Entry entry) {
Object r;
if (entry.getValue() instanceof Timestamp) {
r = ((Timestamp) entry.getValue()).toLocalDateTime();
} else if (entry.getValue() instanceof java.sql.Date) {
r = ((java.sql.Date) entry.getValue()).toLocalDate();
} else if (entry.getValue() instanceof Time) {
r = ((Time) entry.getValue()).toLocalTime();
} else {
r = entry.getValue();
}
return r;
}
public List selectForList(Class entityClazz, Map params, String sql) {
Object[] result = packageSelect(sql, params, dialect.getDialectType());
List> list = jdbcTemplate.queryForList((String) result[0], (Object[]) result[1]);
return entityClazz.isAssignableFrom(Map.class) ? (List) list : list.stream().map(row -> convertRsToObj(row, entityClazz))
.collect(Collectors.toList());
}
public Page selectForPaging(Class entityClazz, MethodConstruction method, String sql) {
Object[] result = packageSelect(sql, method.getParamsMap(), dialect.getDialectType());
String countSql = wrapCountSql((String) result[0]);
String pagedSql = wrapPagingSql((String) result[0], method.getPageNumber(), method.getPageSize());
long totalRecords = jdbcTemplate.queryForObject(countSql, (Object[]) result[1], Long.class);
List> list = jdbcTemplate.queryForList(pagedSql, (Object[]) result[1]);
List objects = entityClazz.isAssignableFrom(Map.class) ? (List) list : list.stream().map(row -> convertRsToObj(row, entityClazz))
.collect(Collectors.toList());
return Page.build(method.getPageNumber(), method.getPageSize(), totalRecords, objects);
}
public Object[] packageSelect(String sql, Map params, DialectType dialectType) {
Matcher m = FIELD_PLACE_HOLDER_PATTERN.matcher(sql);
List matchRegexList = new ArrayList<>();
//将#{...}抠出来
while (m.find()) {
matchRegexList.add(m.group());
}
List list = new ArrayList<>();
//将值不为空的key用?替换
for (String key : matchRegexList) {
// #{key},去掉#{}和空格,获取真实的key
key = key.substring(2, key.length() - 1).replace(" ", EMPTY);
Object v = params.get(key);
if (v != null) {
sql = sql.replaceFirst("\\#\\{\\s*" + key + "\\s*\\}", "?");
list.add(v);
}
}
SQLSelectStatement statement;
switch (dialectType) {
case H2:
case MYSQL:
statement = (SQLSelectStatement) new MySqlStatementParser(sql).parseSelect();
break;
case ORACLE:
statement = (SQLSelectStatement) new OracleStatementParser(sql).parseStatement();
break;
case POSTGRE:
statement = (SQLSelectStatement) new PGSQLStatementParser(sql).parseStatement();
break;
case SQLSERVER:
statement = (SQLSelectStatement) new SQLServerStatementParser(sql).parseStatement();
break;
case DB2:
statement = (SQLSelectStatement) new DB2StatementParser(sql).parseStatement();
break;
case PHOENIX:
statement = (SQLSelectStatement) new PhoenixStatementParser(sql).parseStatement();
break;
default:
statement = (SQLSelectStatement) new SQLStatementParser(sql).parseStatementList().get(0);
break;
}
if (sql.contains("#{")) {
SQLExpr sqlExpr = ((SQLSelectQueryBlock) statement.getSelect().getQuery()).getWhere();
formatWhere(sqlExpr);
}
if (sql.contains(STAR)) {
SQLTableSource sqlTableSource = ((SQLSelectQueryBlock) statement.getSelect().getQuery()).getFrom();
List selectList = ((SQLSelectQueryBlock) statement.getSelect().getQuery()).getSelectList();
List addList = new ArrayList<>();
formatFrom(sqlTableSource, selectList, addList);
selectList.addAll(addList);
}
sql = statement.toString();
return new Object[]{sql, list.toArray()};
}
/**
* 格式化select中的 * 为对应table 字段
*/
private void formatFrom(SQLTableSource sqlTableSource, List selectList, List addList) {
if (sqlTableSource == null) {
return;
}
if (sqlTableSource instanceof SQLExprTableSource) {
doFormat((SQLExprTableSource) sqlTableSource, selectList, addList);
}
if (sqlTableSource instanceof SQLJoinTableSource) {
formatFrom(((SQLJoinTableSource) sqlTableSource).getRight(), selectList, addList);
formatFrom(((SQLJoinTableSource) sqlTableSource).getLeft(), selectList, addList);
}
}
private void doFormat(SQLExprTableSource sqlTableSource, List selectList, List addList) {
EntityContainer.EntityClassInfo entityClassInfo = EntityContainer.getEntityClassByClazz(((SQLIdentifierExpr) sqlTableSource.getExpr()).getName());
if (entityClassInfo == null) {
return;
}
Iterator iterator = selectList.iterator();
while (iterator.hasNext()) {
SQLSelectItem sqlSelectItem = iterator.next();
if (sqlSelectItem.getExpr() instanceof SQLPropertyExpr) {
SQLPropertyExpr expr = (SQLPropertyExpr) sqlSelectItem.getExpr();
SQLIdentifierExpr exprOwner = (SQLIdentifierExpr) expr.getOwner();
if ((exprOwner.getName() + POINT + expr.getName()).equals(sqlTableSource.getAlias() + POINT + STAR)) {
iterator.remove();
entityClassInfo.columns.forEach((filedName, column) -> addWhenAlias(addList, exprOwner, column));
}
} else if (sqlSelectItem.getExpr() instanceof SQLObjectImpl) {
iterator.remove();
entityClassInfo.columns.forEach((filedName, column) -> addList.add(new SQLSelectItem(new SQLIdentifierExpr(leftDecorated + column.columnName + rightDecorated))));
}
}
}
private void addWhenAlias(List addList, SQLIdentifierExpr exprOwner, EntityContainer.EntityClassInfo.Column column) {
if (column.columnName.equals("id") || column.columnName.equals("created_by") || column.columnName.equals("updated_by") || column.columnName.equals("created_time") ||
column.columnName.equals("updated_time"))
return;
addList.add(new SQLSelectItem(new SQLPropertyExpr(exprOwner.getName(), leftDecorated + column.columnName + rightDecorated)));
}
private static String underlineToCamel(String param) {
if (param == null || EMPTY.equals(param.trim())) {
return EMPTY;
}
int len = param.length();
StringBuilder sb = new StringBuilder(len);
for (int i = 0; i < len; i++) {
char c = param.charAt(i);
if (c == UNDERLINE) {
if (++i < len) {
sb.append(Character.toUpperCase(param.charAt(i)));
}
} else {
sb.append(c);
}
}
return sb.toString();
}
public static void formatWhere(SQLExpr sqlExpr) {
if (sqlExpr == null) {
return;
}
if (sqlExpr instanceof SQLBetweenExpr
|| sqlExpr instanceof SQLInListExpr
|| ((SQLBinaryOpExpr) sqlExpr).getLeft() instanceof SQLIdentifierExpr
|| ((SQLBinaryOpExpr) sqlExpr).getLeft() instanceof SQLPropertyExpr) {
doFormatWhere(sqlExpr);
} else {
formatWhere(((SQLBinaryOpExpr) sqlExpr).getRight());
formatWhere(((SQLBinaryOpExpr) sqlExpr).getLeft());
}
}
private static void doFormatWhere(SQLExpr sqlExpr) {
String itemStr;
if (sqlExpr instanceof SQLBetweenExpr) {
itemStr = ((SQLBetweenExpr) sqlExpr).getBeginExpr().toString() + ((SQLBetweenExpr) sqlExpr).getEndExpr().toString();
} else if (sqlExpr instanceof SQLInListExpr) {
itemStr = ((SQLInListExpr) sqlExpr).getTargetList().toString();
} else {
itemStr = sqlExpr.toString();
}
if (FIELD_PLACE_HOLDER_PATTERN.matcher(itemStr).find()) {
if (sqlExpr.getParent() instanceof SQLBinaryOpExpr) {
((SQLBinaryOpExpr) sqlExpr.getParent()).replace(sqlExpr, null);
} else if (sqlExpr.getParent() instanceof SQLSelectQueryBlock) {
((SQLSelectQueryBlock) sqlExpr.getParent()).replace(sqlExpr, null);
}
}
}
public JdbcTemplate getJdbcTemplate() {
return jdbcTemplate;
}
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public String getJdbcUrl() {
return jdbcUrl;
}
public void setJdbcUrl(String jdbcUrl) {
this.jdbcUrl = jdbcUrl;
}
}