shikeying
2024-02-23 1d6e7763f4a30272cc0818ea12f83697b7375c45
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
package com.iplatform.mybatis.service;
 
import com.iplatform.mybatis.domain.GenTable;
import com.iplatform.mybatis.domain.GenTableColumn;
import com.iplatform.mybatis.util.DataTypeUtils;
import com.iplatform.mybatis.util.SqlUtils;
import com.walker.db.DatabaseType;
import com.walker.infrastructure.utils.DateUtils;
import com.walker.infrastructure.utils.StringUtils;
import com.walker.jdbc.JdbcInspector;
import com.walker.jdbc.service.BaseServiceImpl;
import org.springframework.stereotype.Service;
 
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
@Service
public class MetaDataServiceImpl extends BaseServiceImpl {
 
    /**
     * 返回从元数据中查询的表结构信息
     * @param tableName 表名称,可以是表前缀
     * @param isPrecision 是否精确查找,如果是则仅返回和表名一样的表结构。
     * @param packageName 包名称,必填
     * @param moduleName 模块名称,选填
     * @param businessName 业务名称,选填
     * @param functionName 功能名称,选填
     * @return
     * @date 2024-02-20
     */
    public List<GenTable> queryDatabaseTableInfo(String tableName, boolean isPrecision
            , String packageName, String moduleName, String businessName, String functionName){
        List<GenTable> genTableList = new ArrayList<>(8);
        DatabaseType databaseType = JdbcInspector.getInstance().getPrimaryDatabaseType();
        log.debug("databaseType = " + databaseType.toString());
        if(DataTypeUtils.isOracle(databaseType)){
            // oracle元数据中表名都是大写
            tableName = tableName.toUpperCase();
        } else {
            tableName = tableName.toLowerCase();
        }
 
        Map<String, Object> sqlMap = new HashMap<>();
        if(isPrecision){
            sqlMap.put("tablename", "%" + tableName);
        } else {
            sqlMap.put("tablename", tableName + "%");
        }
 
        String sql_table = "";
//        String sql_pk = "";
        String sql_column = "";
 
        if (DataTypeUtils.isOracle(databaseType)) {
            sql_table = "select table_name from user_tables where table_name like :tablename order by table_name desc";
//            sql_pk = "select  col.table_name,col.column_name from user_constraints con,user_cons_columns col where con.constraint_name=col.constraint_name and con.constraint_type='P' and col.table_name like :tablename ";
            sql_column = SqlUtils.ORACLE_QUERY_COLUMNS;
        } else if(DataTypeUtils.isMysql(databaseType)) {
            sql_table = "select table_name from information_schema.tables where table_schema=(SELECT DATABASE()) and table_name like :tablename order by table_name desc";
//            sql_pk = "select table_name,column_name from INFORMATION_SCHEMA.Columns where column_key='PRI' AND table_schema=(SELECT DATABASE()) and table_name like :tablename";
            sql_column = "select table_name,column_name,data_type,NUMERIC_PRECISION data_precision,NUMERIC_SCALE data_scale, column_key from INFORMATION_SCHEMA.Columns where table_schema=(SELECT DATABASE()) and table_name like :tablename order by table_name,ordinal_position\n";
 
        } else if(databaseType == DatabaseType.POSTGRES){
            sql_table = "SELECT c.relname table_name from pg_class c, pg_namespace n  where c.relkind = 'r' and n.nspname = 'public' and c.relnamespace = n.oid and c.relname like :tablename";
            sql_column = SqlUtils.SQL_PG_FIELDS;
            log.debug("POSTGRES......");
 
        } else {
            throw new UnsupportedOperationException("(po生成)不支持的数据库类型:" + databaseType);
        }
        List<Map<String, Object>> table_list = this.dao.select(sql_table, sqlMap);
        List<Map<String, Object>> column_list = this.dao.select(sql_column, sqlMap);
 
        log.debug("生成表结构(PO) = {}", table_list);
 
        for (Map<String, Object> table : table_list) {
            String table_name = table.get("table_name").toString();
            String pk_name = "id";
            String pk_type = "NUMBER";
            List<Map<String, Object>> column_temp = new ArrayList<>();
 
            String columnKey = null;
            for (Map<String, Object> column : column_list) {
                if(!column.get("table_name").toString().equalsIgnoreCase(table.get("table_name").toString())){
                    // 只有当前表字段才处理,老代码遍历所有表字段有问题。2022-09-20
                    continue;
                }
                // 2022-09-07 修改(后续有oracle需求还需要改)
                if(column.get("column_key") != null){
                    columnKey = column.get("column_key").toString();
                    if(DataTypeUtils.isPrimaryColumn(columnKey)){
                        // mysql主键字段是:PRI,oracle是:P,2023-03-03 修改
                        pk_name = column.get("column_name").toString().toLowerCase();
                        pk_type = column.get("data_type").toString().toLowerCase();
                        log.info(table_name + " 找到主键:" + pk_name + ", " + pk_type);
                        continue;
                    }
                }
 
                if ((table_name.equalsIgnoreCase(column.get("table_name").toString())) && (!column.get("column_name").toString().equalsIgnoreCase(pk_name))) {
                    String type = column.get("data_type").toString().toLowerCase();
                    column.put("name", column.get("column_name").toString().toLowerCase());
                    if ((type.equalsIgnoreCase("number")) || (type.equalsIgnoreCase("decimal"))) {
                        int precision = Integer.valueOf(column.get("data_precision") == null ? "0" : column.get("data_precision").toString()).intValue();
                        int scale = Integer.valueOf(column.get("data_scale") == null ? "0" : column.get("data_scale").toString()).intValue();
                        type = DataTypeUtils.getType(type, precision, scale);
                    }
                    column.put("type", type);
                    column_temp.add(column);
                }
            }
            table.put("table_name", table_name.toLowerCase());
            table.put("pk_name", pk_name);
//            table.put("pk_type", pk_type);
            table.put("pk_type", DataTypeUtils.getType(pk_type, 0, 0));
            table.put("columns", column_temp);
 
            GenTable genTable = this.acquireGenTable(table, packageName, moduleName, businessName, functionName, pk_name);
            genTableList.add(genTable);
        }
        return genTableList;
    }
 
    private GenTable acquireGenTable(Map<String, Object> table
            , String packageName, String moduleName, String businessName, String functionName, String pkName){
        GenTable genTable = new GenTable();
        genTable.setCreateTime(DateUtils.getDateTimeNumber());
        genTable.setTableName(table.get("table_name").toString());
        genTable.setTableComment(StringUtils.EMPTY_STRING);
        genTable.setClassName(StringUtils.transferUnderlineName2Camel(genTable.getTableName(), true));
        genTable.setTplCategory("crud");
        genTable.setGenType("0");
        genTable.setFunctionAuthor("shikeying");
        genTable.setPackageName(packageName);
//        genTable.setGenPath("/");
        if(StringUtils.isNotEmpty(moduleName)){
            genTable.setModuleName(moduleName);
        }
        if(StringUtils.isNotEmpty(businessName)){
            genTable.setBusinessName(businessName);
        }
        if(StringUtils.isNotEmpty(functionName)){
            genTable.setFunctionName(functionName);
        }
 
        List<GenTableColumn> genTableColumnList = new ArrayList<>();
        List<Map<String, Object>> columns = (List<Map<String, Object>>)table.get("columns");
        GenTableColumn genTableColumn = null;
        boolean isPrimaryKey = false;
 
        for(Map<String, Object> map : columns){
            if(StringUtils.isNotEmpty(pkName) && map.get("column_name").toString().equals(pkName)){
                isPrimaryKey = true;
            }
            genTableColumn = this.acquireGenColumn(map, isPrimaryKey);
            if(isPrimaryKey){
                genTable.setPkColumn(genTableColumn);
            }
            genTableColumnList.add(genTableColumn);
        }
        genTable.setColumns(genTableColumnList);
        return genTable;
    }
 
    private GenTableColumn acquireGenColumn(Map<String, Object> map, boolean isPrimaryKey){
        GenTableColumn genTableColumn = new GenTableColumn();
        genTableColumn.setCreateTime(DateUtils.getDateTimeNumber());
        genTableColumn.setColumnName(map.get("column_name").toString());
        genTableColumn.setColumnType(map.get("type").toString());
        genTableColumn.setColumnComment(StringUtils.EMPTY_STRING);
        if(isPrimaryKey){
            genTableColumn.setIsPk("1");
        }
        genTableColumn.setJavaField(StringUtils.transferUnderlineName2Camel(genTableColumn.getColumnName(), true));
        return genTableColumn;
    }
}