小工具-校验实体类和数据库中的字段是否一致
小工具
·
代码
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.diantong.base.mybatis.dao.CommonMapper;
import com.diantong.base.mybatis.pojo.TableColumnsEntity;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.CollectionUtils;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
/**
* @author xiu
* @date 2021/5/25 19:47
* @description 校验mybatis plus 和数据库中的字段是否一致,,只是个校验,,哦哦===》其实用jpa也可以
*/
@Configuration
@Slf4j
public class CheckTableInfoConfig implements ApplicationRunner {
@Autowired(required = false)
private List<BaseMapper<?>> baseMapperList;
@Autowired(required = false)
private CommonMapper commonMapper;
@Override
public void run(ApplicationArguments args) {
if (commonMapper == null || CollectionUtils.isEmpty(baseMapperList)) {
return;
}
StringBuilder allErrorInfo = new StringBuilder();
for (BaseMapper<?> baseMapper : baseMapperList) {
StringBuilder errorInfo = new StringBuilder();
//mapper.class
Class<?> mapperClass = getMapperGenerics(baseMapper.getClass());
//entity.class
Class<?> entityClass = getEntityGenerics(mapperClass);
if (entityClass == null) {
log.info("\n**********mapper:{},未找到对应的实体类模型", mapperClass);
continue;
}
//tableInfo信息
TableInfo tableInfo = TableInfoHelper.getTableInfo(entityClass);
if (tableInfo == null) {
allErrorInfo.append("**********实体类:").append(entityClass).append(",在上下文中未找到对应的mybatis模型").append("\n");
continue;
}
//实体类的字段
List<TableFieldInfo> fieldList = Optional.of(tableInfo).map(TableInfo::getFieldList).orElse(new ArrayList<>());
//从数据库中查询的表字段
List<TableColumnsEntity> list;
try {
List<JSONObject> data = commonMapper.queryObjects("show columns from " + tableInfo.getTableName());
list = data.stream().map(t -> TableColumnsEntity.builder()
.Field(t.getString("Field"))
.Type(t.getString("Type"))
.Null(t.getString("Null"))
.Key(t.getString("Key"))
.Default(t.getString("Default"))
.Extra(t.getString("Extra"))
.build()).collect(Collectors.toList());
} catch (Exception e) {
allErrorInfo.append("**********实体类:").append(entityClass).append(",在数据库中未找到对应的表信息").append("\n");
allErrorInfo.append(tableInfo.getKeyColumn()).append("\t\t\t").append(tableInfo.getKeyType().getName()).append("\n");
fieldList.forEach(t -> allErrorInfo.append(t.getColumn()).append("\t\t\t").append(t.getPropertyType().getName()).append("\n"));
continue;
}
List<TableColumnsEntity> finalList = list;
//循环实体类字段
boolean haveKeyInEntity = finalList.stream().anyMatch(tempList -> Objects.equals(tableInfo.getKeyColumn(), tempList.getField()));
if (!haveKeyInEntity) {
errorInfo.append("表中缺key:\t").append(tableInfo.getKeyColumn()).append("\t\t\t").append(tableInfo.getKeyType().getName()).append("\n");
}
fieldList.forEach(tempField -> {
String column = tempField.getColumn();
boolean b = finalList.stream().anyMatch(tempList -> Objects.equals(column, tempList.getField()));
if (!b) {
errorInfo.append("表中缺字段:\t").append(column).append("\t\t\t").append(tempField.getPropertyType().getName()).append("\n");
}
});
//循环表中字段
list.forEach(tempList -> {
String field = tempList.getField();
boolean b = fieldList.stream().anyMatch(tempField -> Objects.equals(field, tempField.getColumn()) || Objects.equals(field, tableInfo.getKeyColumn()));
if (!b) {
errorInfo.append("entity中缺字段:\t").append(field).append("\t\t\t").append(tempList.getType()).append("\n");
}
});
if (errorInfo.length() > 0) {
allErrorInfo.append("**********实体类模型与数据库对应信息错误:").append(entityClass).append("\n");
allErrorInfo.append(errorInfo);
}
}
if (allErrorInfo.length() > 0) {
allErrorInfo.insert(0, "\n***********************mybatis plus 和 数据库 校验有误**************************************\n");
allErrorInfo.append("***********************mybatis plus 和 数据库 校验有误**************************************\n");
log.error(allErrorInfo.insert(0, "\n").toString());
} else {
log.info("\n***********************mybatis plus 和 数据库 校验成功*******************************");
}
}
private Class<?> getMapperGenerics(Class<?> clazz) {
if (clazz == null) {
return null;
}
try {
Type[] genericInterfaces = clazz.getGenericInterfaces();
return Class.forName(genericInterfaces[0].getTypeName());
} catch (Exception ignored) {
}
return null;
}
private Class<?> getEntityGenerics(Class<?> clazz) {
if (clazz == null) {
return null;
}
try {
Type[] a = clazz.getGenericInterfaces();
for (Type type : a) {
if (type instanceof ParameterizedType) {
ParameterizedType type1 = (ParameterizedType) type;
return (Class<?>) type1.getActualTypeArguments()[0];
}
}
} catch (Exception ignored) {
}
return null;
}
}
效果
更多推荐
已为社区贡献1条内容
所有评论(0)