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.
io.github.shmilyjxs.core.impl.BaseBeanDao Maven / Gradle / Ivy
package io.github.shmilyjxs.core.impl;
import io.github.shmilyjxs.utils.BeanUtil;
import io.github.shmilyjxs.utils.PageResult;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.tuple.Triple;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.jdbc.support.JdbcUtils;
import org.springframework.util.LinkedCaseInsensitiveMap;
import org.springframework.util.ReflectionUtils;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
public abstract class BaseBeanDao extends BaseSqlDao {
private static final Logger logger = LoggerFactory.getLogger(BaseBeanDao.class);
private static final Map, Triple, Map>> CLASS_CACHE = new ConcurrentHashMap<>();
private static Map buildMap(T obj, Map convertMap) {
return buildMap(obj, convertMap, true);
}
private static Map buildMap(T obj, Map convertMap, boolean skipBlank) {
Map beanMap = BeanUtil.beanToMap(obj);
if (skipBlank) {
beanMap = BeanUtil.skipBlank(beanMap);
}
Map map = new LinkedHashMap<>();
for (Map.Entry entry : convertMap.entrySet()) {
if (beanMap.containsKey(entry.getKey())) {
map.put(entry.getValue(), beanMap.get(entry.getKey()));
}
}
return map;
}
@Override
public Triple, Map> getTableInfo(T obj) {
return Optional.of(obj).map(T::getClass).map(this::getTableInfo).get();
}
@Override
public Triple, Map> getTableInfo(Class clazz) {
Triple, Map> triple = CLASS_CACHE.get(clazz);
if (Objects.isNull(triple)) {
synchronized (this) {
triple = CLASS_CACHE.get(clazz);
if (Objects.isNull(triple)) {
String tableName = BeanUtil.getTableName(clazz);
Field idFiled = BeanUtil.idFiled(clazz);
String sql = getDBType().getDialect().columnSql(tableName);
List columnList = scalarList(sql, String.class);
Map map = new LinkedCaseInsensitiveMap<>();
columnList.forEach(e -> map.put(e, e));
columnList.forEach(e -> map.putIfAbsent(JdbcUtils.convertUnderscoreNameToPropertyName(e), e));
columnList.forEach(e -> map.putIfAbsent(BeanUtil.dbToJava(e), e));
Map.Entry entry = new AbstractMap.SimpleImmutableEntry<>(idFiled, Objects.requireNonNull(map.get(idFiled.getName())));
Map convertMap = new LinkedHashMap<>();
Arrays.stream(BeanUtils.getPropertyDescriptors(clazz))
.map(PropertyDescriptor::getName)
.filter(map::containsKey)
.map(e -> new AbstractMap.SimpleImmutableEntry<>(e, map.get(e)))
.sorted(Comparator.comparingInt(e -> columnList.indexOf(e.getValue())))
.forEach(e -> convertMap.put(e.getKey(), e.getValue()));
triple = Triple.of(tableName, entry, Collections.unmodifiableMap(convertMap));
CLASS_CACHE.put(clazz, triple);
}
}
}
logger.info("class {} ===>>> table {}", clazz.getName(), triple.getLeft());
logger.info("id {} ===>>> column {}", triple.getMiddle().getKey().getName(), triple.getMiddle().getValue());
triple.getRight().forEach((key, val) -> logger.info("property {} ===>>> column {}", key, val));
return triple;
}
@Override
public T insert(T obj, boolean skipBlank) {
Triple, Map> tableInfo = getTableInfo(obj);
Field idField = tableInfo.getMiddle().getKey();
ReflectionUtils.makeAccessible(idField);
Object idValue = ReflectionUtils.getField(idField, obj);
if (ObjectUtils.isEmpty(idValue)) {
ReflectionUtils.setField(idField, obj, idGenerator());
}
insert(tableInfo.getLeft(), buildMap(obj, tableInfo.getRight(), skipBlank));
return obj;
}
@Override
public void batchInsert(Collection> objs) {
objs.stream().filter(Objects::nonNull).collect(Collectors.groupingBy(Object::getClass)).forEach((key, val) -> {
Triple, Map> tableInfo = getTableInfo(key);
StringBuilder stringBuilder = new StringBuilder("INSERT INTO ");
stringBuilder.append(tableInfo.getLeft());
stringBuilder.append(tableInfo.getRight().values().stream().collect(Collectors.joining(" , ", " ( ", " ) ")));
stringBuilder.append("VALUES");
stringBuilder.append(tableInfo.getRight().values().stream().map(e -> "?").collect(Collectors.joining(" , ", " ( ", " ) ")));
String sql = stringBuilder.toString();
List batchArgs = new ArrayList<>();
Field idField = tableInfo.getMiddle().getKey();
ReflectionUtils.makeAccessible(idField);
val.forEach(obj -> {
Object idValue = ReflectionUtils.getField(idField, obj);
if (ObjectUtils.isEmpty(idValue)) {
ReflectionUtils.setField(idField, obj, idGenerator());
}
Map map = buildMap(obj, tableInfo.getRight(), false);
batchArgs.add(map.values().toArray());
});
logger.info("sql = {}", sql);
batchArgs.forEach(e -> logger.info("args = {}", Arrays.asList(e)));
getJdbcTemplate().batchUpdate(sql, batchArgs);
});
}
@Override
public T updateById(T obj, boolean skipBlank) {
Triple, Map> tableInfo = getTableInfo(obj);
update(tableInfo.getLeft(), buildMap(obj, tableInfo.getRight(), skipBlank), tableInfo.getMiddle().getValue());
return obj;
}
@Override
public void batchUpdate(Collection> objs) {
objs.stream().filter(Objects::nonNull).collect(Collectors.groupingBy(Object::getClass)).forEach((key, val) -> {
Triple, Map> tableInfo = getTableInfo(key);
StringBuilder stringBuilder = new StringBuilder("UPDATE ");
stringBuilder.append(tableInfo.getLeft());
stringBuilder.append(" SET ");
stringBuilder.append(tableInfo.getRight().values().stream().filter(e -> ObjectUtils.notEqual(e, tableInfo.getMiddle().getValue())).map(e -> e.concat(" = ?")).collect(Collectors.joining(" , ")));
stringBuilder.append(" WHERE ");
stringBuilder.append(tableInfo.getMiddle().getValue().concat(" = ?"));
String sql = stringBuilder.toString();
List batchArgs = new ArrayList<>();
val.forEach(obj -> {
Map map = buildMap(obj, tableInfo.getRight(), false);
Object idValue = map.remove(tableInfo.getMiddle().getValue());
batchArgs.add(ArrayUtils.add(map.values().toArray(), idValue));
});
logger.info("sql = {}", sql);
batchArgs.forEach(e -> logger.info("args = {}", Arrays.asList(e)));
getJdbcTemplate().batchUpdate(sql, batchArgs);
});
}
@Override
public T insertOrUpdate(T obj, boolean skipBlank) {
Triple, Map> tableInfo = getTableInfo(obj);
Field idField = tableInfo.getMiddle().getKey();
ReflectionUtils.makeAccessible(idField);
Object idValue = ReflectionUtils.getField(idField, obj);
if (ObjectUtils.isEmpty(idValue)) {
ReflectionUtils.setField(idField, obj, idGenerator());
insert(tableInfo.getLeft(), buildMap(obj, tableInfo.getRight(), skipBlank));
} else {
Map map = getMap(tableInfo.getLeft(), tableInfo.getMiddle().getValue(), idValue);
if (Objects.isNull(map)) {
insert(tableInfo.getLeft(), buildMap(obj, tableInfo.getRight(), skipBlank));
} else {
update(tableInfo.getLeft(), buildMap(obj, tableInfo.getRight(), skipBlank), tableInfo.getMiddle().getValue());
}
}
return obj;
}
@Override
public void batchInsertOrUpdate(Collection> objs) {
List insertList = new ArrayList<>();
List updateList = new ArrayList<>();
objs.stream().filter(Objects::nonNull).collect(Collectors.groupingBy(Object::getClass)).forEach((key, val) -> {
Triple, Map> tableInfo = getTableInfo(key);
Field idField = tableInfo.getMiddle().getKey();
ReflectionUtils.makeAccessible(idField);
List> idList = val.stream().map(e -> ReflectionUtils.getField(idField, e)).filter(ObjectUtils::isNotEmpty).collect(Collectors.toList());
Map, List>> idGroup = getList(tableInfo.getLeft(), tableInfo.getMiddle().getValue(), idList).stream().collect(Collectors.groupingBy(e -> e.get(tableInfo.getMiddle().getValue())));
val.forEach(obj -> {
Object idValue = ReflectionUtils.getField(idField, obj);
if (ObjectUtils.isEmpty(idValue)) {
insertList.add(obj);
} else if (idGroup.containsKey(idValue)) {
updateList.add(obj);
} else {
insertList.add(obj);
}
});
});
batchInsert(insertList);
batchUpdate(updateList);
}
@Override
public int deleteById(T obj) {
Triple, Map> tableInfo = getTableInfo(obj);
Field idFiled = tableInfo.getMiddle().getKey();
ReflectionUtils.makeAccessible(idFiled);
Object idValue = ReflectionUtils.getField(idFiled, obj);
return delete(tableInfo.getLeft(), tableInfo.getMiddle().getValue(), idValue);
}
@Override
public void batchDelete(Collection> objs) {
objs.stream().filter(Objects::nonNull).collect(Collectors.groupingBy(Object::getClass)).forEach((key, val) -> {
Triple, Map> tableInfo = getTableInfo(key);
Field idFiled = tableInfo.getMiddle().getKey();
ReflectionUtils.makeAccessible(idFiled);
List> idValues = val.stream().map(e -> ReflectionUtils.getField(idFiled, e)).collect(Collectors.toList());
batchDelete(tableInfo.getLeft(), tableInfo.getMiddle().getValue(), idValues);
});
}
@Override
public int delete(ID idValue, Class mappedClass) {
Triple, Map> tableInfo = getTableInfo(mappedClass);
return delete(tableInfo.getLeft(), tableInfo.getMiddle().getValue(), idValue);
}
@Override
public int batchDelete(Collection idValues, Class mappedClass) {
Triple, Map> tableInfo = getTableInfo(mappedClass);
return batchDelete(tableInfo.getLeft(), tableInfo.getMiddle().getValue(), idValues);
}
@Override
public T getBean(ID idValue, Class mappedClass) {
Triple, Map> tableInfo = getTableInfo(mappedClass);
return getBean(tableInfo.getLeft(), tableInfo.getMiddle().getValue(), idValue, mappedClass);
}
@Override
public List getBeans(Collection idValues, Class mappedClass, String... orderBy) {
Triple, Map> tableInfo = getTableInfo(mappedClass);
return getBeans(tableInfo.getLeft(), tableInfo.getMiddle().getValue(), idValues, mappedClass, orderBy);
}
@Override
public int delete(T example) {
Triple, Map> tableInfo = getTableInfo(example);
return delete(tableInfo.getLeft(), buildMap(example, tableInfo.getRight()));
}
@Override
public T getBean(T example) {
Triple, Map> tableInfo = getTableInfo(example);
return getBean(tableInfo.getLeft(), buildMap(example, tableInfo.getRight()), (Class) example.getClass());
}
@Override
public List getBeans(T example, String... orderBy) {
Triple, Map> tableInfo = getTableInfo(example);
return getBeans(tableInfo.getLeft(), buildMap(example, tableInfo.getRight()), (Class) example.getClass(), orderBy);
}
@Override
public PageResult getPage(T example, long pageNum, long pageSize, String... orderBy) {
Triple, Map> tableInfo = getTableInfo(example);
return selectPage(tableInfo.getLeft(), buildMap(example, tableInfo.getRight()), pageNum, pageSize, (Class) example.getClass(), orderBy);
}
}