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.
cn.tenfell.plugins.dbgenerate.utils.DocUtils Maven / Gradle / Ivy
package cn.tenfell.plugins.dbgenerate.utils;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.ModifierUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import cn.tenfell.plugins.dbgenerate.annotation.Table;
import cn.tenfell.plugins.dbgenerate.annotation.TableColumn;
import cn.tenfell.plugins.dbgenerate.annotation.TableNoExist;
import cn.tenfell.plugins.dbgenerate.config.DbGenerateProperties;
import cn.tenfell.plugins.dbgenerate.entity.ColumnProp;
import cn.tenfell.plugins.dbgenerate.entity.DefaultAnnotation;
import cn.tenfell.plugins.dbgenerate.entity.TableColumnProp;
import cn.tenfell.plugins.dbgenerate.entity.TableProp;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.dialect.Database;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.dialect.spi.DatabaseMetaDataDialectResolutionInfoAdapter;
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
import org.hibernate.type.AbstractSingleColumnStandardBasicType;
import org.hibernate.type.StringType;
import javax.sql.DataSource;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.Types;
import java.util.*;
/**
* 文档生成工具类
* @author fs
*/
@UtilityClass
@Slf4j
public class DocUtils {
public static String time;
public final static DbGenerateProperties dbGenerateProperties = new DbGenerateProperties();
private static Map> allTypes;
private static Map allDbCodes;
public static Dialect sqlDialect;
public static DataSource dataSource;
public static Map allDataByDb = new HashMap<>();
public static Map allDataByBeans = new HashMap<>();
public static List> allKeys = new ArrayList<>();
public void init(DataSource ds){
Assert.notNull(dbGenerateProperties.getBeanPackages(),"当前没有配置实体扫描路径");
dataSource = ds;
Connection connection = null;
try{
connection = dataSource.getConnection();
}catch (Exception e){
}
Assert.notNull(connection,"无法获取数据库连接信息");
DatabaseMetaData metaData = null;
try{
metaData = connection.getMetaData();
}catch (Exception e){
}
Assert.notNull(connection,"无法获取连接池信息");
Assert.notNull(metaData,"无法获取metaData");
try{
SqlUtils.catalog =connection.getCatalog();
}catch (Exception e){
Assert.isTrue(false,"无法读取catalog");
}
try{
SqlUtils.schema =connection.getSchema();
}catch (Exception e){
Assert.isTrue(false,"无法读取schema");
}
DialectResolutionInfo info = new DatabaseMetaDataDialectResolutionInfoAdapter(metaData);
Dialect dialect = null;
for ( Database database : Database.values() ) {
dialect = database.resolveDialect( info );
if ( dialect != null ) {
break;
}
}
Assert.notNull(dialect,"暂时无法支持你的数据库");
sqlDialect = dialect;
ReflectUtil.invoke(sqlDialect,"registerColumnType",Types.DOUBLE,"double($p,$s)");
ReflectUtil.invoke(sqlDialect,"registerColumnType",Types.FLOAT,"float($p,$s)");
updateData();
DocUtils.time = DateUtil.now();
}
public void updateData(){
allDataByDb = null;
allDataByBeans=null;
allKeys = null;
/**
* 从实体获取所有属性
*/
createBeanData();
/**
*从数据库获取所有属性
*/
createDbData();
/**
* 进行数据组合
*/
createKeys();
}
private static void createKeys(){
allKeys = new ArrayList<>();
Map> tempAllKeys = new HashMap<>();
List beans = new ArrayList<>(allDataByBeans.values());
List bds = new ArrayList<>(allDataByDb.values());
beans.addAll(bds);
for(TableColumnProp one:beans){
TableProp table = one.getTable();
Set colSets = tempAllKeys.get(table.getTableName());
if(colSets == null){
colSets = new HashSet<>();
tempAllKeys.put(table.getTableName(),colSets);
}
Map columnPropMap = one.getColumns();
List columnProps = new ArrayList<>(columnPropMap.values());
for(ColumnProp columnProp:columnProps){
colSets.add(columnProp.getColumn());
}
}
Set keys = tempAllKeys.keySet();
for(String key:keys){
Map map = new HashMap<>();
map.put("table",key);
List columns = new ArrayList<>();
columns.addAll(tempAllKeys.get(key));
columns.sort(new Comparator() {
@Override
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
});
map.put("columns",columns);
allKeys.add(map);
if(allDataByDb.get(key) == null){
TableColumnProp tableColumnProp = new TableColumnProp();
tableColumnProp.setTable(new TableProp());
tableColumnProp.setColumns(new HashMap());
allDataByDb.put(key,tableColumnProp);
}
if(allDataByBeans.get(key) == null){
TableColumnProp tableColumnProp = new TableColumnProp();
tableColumnProp.setTable(new TableProp());
tableColumnProp.setColumns(new HashMap());
allDataByBeans.put(key,tableColumnProp);
}
}
allKeys.sort(new Comparator>() {
@Override
public int compare(Map o1, Map o2) {
String t1 = (String)o1.get("table");
String t2 = (String)o2.get("table");
return t1.compareTo(t2);
}
});
}
private static void createBeanData(){
allDataByBeans = new HashMap<>();
Set clazzs = new HashSet<>();
for(String pka:dbGenerateProperties.getBeanPackages()){
clazzs.addAll(ClassUtil.scanPackage(pka));
}
for(Class clazz:clazzs){
TableNoExist tne = (TableNoExist)clazz.getAnnotation(TableNoExist.class);
if(tne != null){
continue;
}
Table taba = (Table)clazz.getAnnotation(Table.class);
if(taba == null){
taba = DefaultAnnotation.class.getAnnotation(Table.class);
}
TableColumnProp tableColumnProp = new TableColumnProp();
TableProp table = new TableProp();
table.setComment(taba.comment());
if(StrUtil.isNotBlank(taba.tableName())){
table.setTableName(taba.tableName());
}else{
table.setTableName(StrUtil.toUnderlineCase(clazz.getSimpleName()));
}
tableColumnProp.setTable(table);
Field[] fields = ReflectUtil.getFields(clazz);
Map columns = new HashMap<>();
for(Field field:fields){
if(ModifierUtil.isStatic(field)){
continue;
}
TableNoExist tfne = field.getAnnotation(TableNoExist.class);
if(tfne != null){
continue;
}
Type javaType = field.getGenericType();
if(javaType == null || !(javaType instanceof Class)){
continue;
}
TableColumn tabCol = field.getAnnotation(TableColumn.class);
if(tabCol == null){
tabCol = DefaultAnnotation.tableColumnMap().get(javaType.getTypeName());
}
if(tabCol == null){
continue;
}
Integer code = tabCol.type().getVendorTypeNumber();
String type = null;
if(code == Types.OTHER){
if(javaType == String.class){
type = sqlDialect.getHibernateTypeName(Types.VARCHAR,tabCol.length(),tabCol.length(),tabCol.decimal());
}else{
type = getHibernateTypeByClass((Class)javaType);
}
}else{
type = sqlDialect.getHibernateTypeName(code,tabCol.length(),tabCol.length(),tabCol.decimal());
}
if(StrUtil.isBlank(type)){
continue;
}
ColumnProp columnProp = new ColumnProp();
columnProp.setPrimaryIs(tabCol.isprimary());
columnProp.setNullIs(tabCol.isnull());
columnProp.setDecimal(Convert.toInt(tabCol.decimal()));
columnProp.setLength(Convert.toInt(tabCol.length()));
if(StrUtil.isNotBlank(tabCol.column())){
columnProp.setColumn(tabCol.column());
}else{
columnProp.setColumn(StrUtil.toUnderlineCase(field.getName()));
}
columnProp.setComment(tabCol.comment());
columnProp.setType(type);
columns.put(columnProp.getColumn(),columnProp);
}
tableColumnProp.setColumns(columns);
allDataByBeans.put(table.getTableName(),tableColumnProp);
}
}
public static void createDbData(){
allDataByDb = new HashMap<>();
try{
Connection connection=dataSource.getConnection();
String catalog = connection.getCatalog();
String schema = connection.getSchema();
final DatabaseMetaData databaseMetaData = connection.getMetaData();
String[] types = new String[]{"TABLE"};
ResultSet resultSet = databaseMetaData.getTables(catalog,schema,"%",types);
List list = new ArrayList<>();
while (resultSet.next()) {
String name = resultSet.getString( "TABLE_NAME" );
String comment = resultSet.getString("REMARKS");
TableColumnProp tableColumnProp = new TableColumnProp();
TableProp tableProp = new TableProp();
tableProp.setTableName(name);
tableProp.setComment(comment);
tableColumnProp.setTable(tableProp);
list.add(tableColumnProp);
}
resultSet.close();
for(TableColumnProp tableColumnProp:list){
ResultSet colRes = databaseMetaData.getColumns(catalog,schema,tableColumnProp.getTable().getTableName(),"%");
Map columns = new HashMap<>();
tableColumnProp.setColumns(columns);
allDataByDb.put(tableColumnProp.getTable().getTableName(),tableColumnProp);
while(colRes.next()){
Integer code = colRes.getInt( "DATA_TYPE" );
int length = colRes.getInt( "COLUMN_SIZE" );
int scale = colRes.getInt( "DECIMAL_DIGITS" );
String type = null;
try{
type = sqlDialect.getHibernateTypeName(code,length,length,scale);
}catch (Exception e){
System.out.println("当前类型不受支持:"+code);
}
if(StrUtil.isBlank(type)){
System.out.println("当前类型不受支持:"+code);
continue;
}
if(getAllTypes().get(type) == null){
System.out.println("当前类型不受支持:"+code);
continue;
}
ColumnProp column = new ColumnProp();
column.setColumn(colRes.getString( "COLUMN_NAME" ));
column.setType(type);
column.setLength(length);
column.setComment(colRes.getString("REMARKS"));
column.setDecimal(scale);
column.setNullIs(StrUtil.equals(colRes.getString( "IS_NULLABLE" ).toUpperCase(),"YES"));
column.setPrimaryIs(false);
columns.put(column.getColumn(),column);
}
colRes.close();
ResultSet pkRes=databaseMetaData.getPrimaryKeys(catalog,schema,tableColumnProp.getTable().getTableName());
while(pkRes.next()){
Collection tmpColumns = columns.values();
for(ColumnProp columnProp:tmpColumns){
String columnName = pkRes.getString("COLUMN_NAME");
if(!StrUtil.equals(columnProp.getColumn(),columnName)){
continue;
}
columnProp.setPrimaryIs(true);
}
}
pkRes.close();
}
}catch (Exception e){
throw new RuntimeException(e);
}
}
private static String getHibernateTypeByClass(Class clazz){
String type = null;
Collection> list = getAllTypes().values();
for(Map map:list){
Class one = (Class)map.get("javaClass");
if(ClassUtil.isAssignable(clazz,one) && ClassUtil.isAssignable(one,clazz)){
type = (String)map.get("name");
break;
}
}
return type;
}
public static Map> getAllTypes(){
if(allTypes != null){
return allTypes;
}
Set> sets = ClassUtil.scanPackageBySuper("org.hibernate.type", AbstractSingleColumnStandardBasicType.class);
allTypes = new HashMap<>();
for(Class> one:sets){
String name = null;
Object obj = null;
try{
obj = ReflectUtil.newInstanceIfPossible(one);
name = ReflectUtil.invoke(obj,"getName");
}catch (Exception e){
}
if(name == null){
continue;
}
java.lang.reflect.Type type = one.getGenericSuperclass();
if(!(type instanceof ParameterizedType)){
continue;
}
ParameterizedType pt = (ParameterizedType)type;
java.lang.reflect.Type[] children = pt.getActualTypeArguments();
if(children.length != 1){
continue;
}
Type child = children[0];
if(!(child instanceof Class)){
continue;
}
Class the = (Class)child;
Map temp = new HashMap<>();
temp.put("hibernateClass",one);
temp.put("hibernateObj",obj);
temp.put("javaClass",the);
temp.put("name",name);
allTypes.put(name,temp);
}
return allTypes;
}
public static org.hibernate.type.Type getTypeByHibernateName(String name){
Collection> list = getAllTypes().values();
org.hibernate.type.Type type = null;
for(Map one:list){
if(StrUtil.equals(Convert.toStr(one.get("name")),name)){
type = (org.hibernate.type.Type)(one.get("hibernateObj"));
break;
}
}
if(type == null){
type = StringType.INSTANCE;
}
return type;
}
}