shikeying
2024-01-11 3b67e947e36133e2a40eb2737b15ea375e157ea0
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
package com.walker.dbmeta.util;
 
import com.walker.connector.Address;
import com.walker.db.DatabaseType;
import com.walker.dbmeta.DatabaseMetaEngine;
import com.walker.dbmeta.FieldInfo;
import com.walker.dbmeta.support.MySQLMetaEngine;
import com.walker.dbmeta.support.PostgresMetaEngine;
import com.walker.infrastructure.utils.StringUtils;
 
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
 
/**
 * 系统多表存储功能,数据库元数据引擎对象管理类。</p>
 * 因为目前系统使用了多种数据库,如:mysql、pg等,因此分拆表也区分不同类型数据库,所以需要前端传入数据库信息来获得元数据引擎对象。
 * @author shikeying
 * @date 2016年9月26日
 *
 */
public class DatabaseMetaEngineUtils {
 
    private static final Map<Address, DatabaseMetaEngine> cached = new ConcurrentHashMap<Address, DatabaseMetaEngine>(2);
 
    /**
     * 通过 ResultSetMetaData 判断是否有给定名称的字段。
     * @param columnName 给定字段名称
     * @param rsMetaData
     * @return
     * @throws SQLException
     * @date 2022-11-26
     */
    public static final boolean isContainColumnName(String columnName, ResultSetMetaData rsMetaData) throws SQLException {
        int numberOfColumns = rsMetaData.getColumnCount();
        String column = null;
        for (int i = 1; i < numberOfColumns + 1; i++) {
            column = rsMetaData.getColumnName(i);
            // Get the name of the column's table name
            if (column.equalsIgnoreCase(columnName)) {
//                    System.out.println("Bingo!");
                return true;
            }
        }
        return false;
    }
 
    /**
     * 获得系统多数据库中的某个数据库的元数据引擎对象。
     * @param address
     * @param databaseType
     * @return
     */
    public static final DatabaseMetaEngine getDatabaseMetaEngine(Address address, DatabaseType databaseType){
        if(address == null){
            throw new IllegalArgumentException();
        }
        DatabaseMetaEngine engine = cached.get(address);
        if(engine == null){
            engine = createDatabaseMetaEngine(address, databaseType);
            cached.put(address, engine);
        }
        return engine;
    }
    
    private static DatabaseMetaEngine createDatabaseMetaEngine(Address address, DatabaseType databaseType){
        DatabaseMetaEngine engine = null;
        if(databaseType == DatabaseType.MYSQL){
            engine = new MySQLMetaEngine();
        } else if(databaseType == DatabaseType.POSTGRES){
            engine = new PostgresMetaEngine();
        }
        engine.initialize();
        return engine;
    }
    
    public static final String getLikeConditionArg(String value){
        return new StringBuilder().append("%").append(value).append("%").toString();
    }
    
    /**
     * 生成字段对象
     * @param fieldName 字段名称
     * @param value 采集的数据值
     * @param tableName 表名
     * @return
     */
    public static final FieldInfo getFieldInfo(String fieldName, Object value, String tableName){
        FieldInfo fi = new FieldInfo();
        fi.setFieldName(fieldName.toLowerCase());
        fi.setTableName(tableName.toLowerCase());
        
        // 如果值不存在,则该字段默认为字符串类型
        if(value == null){
            fi.setDataType(FieldInfo.TYPE_STRING);
            return fi;
        }
        
        Class<?> type = StringUtils.getNumbericType(value.toString());
        if(type == Long.class){
            fi.setDataType(FieldInfo.TYPE_LONG);
        } else if(type == Double.class){
            fi.setDataType(FieldInfo.TYPE_DOUBLE);
        } else if(type == String.class){
            fi.setDataType(FieldInfo.TYPE_STRING);
        } else {
            throw new UnsupportedOperationException("不支持的数据类型:" + type.getName());
        }
        
        return fi;
    }
    
    /**
     * 搜索字段列表中,数据版本字段类型是否数值。</p>
     * 注意:必须是长整形(Long),其他都不行
     * @param fieldList
     * @param dataVersionField
     * @return
     */
    public static final boolean isNumberField(List<FieldInfo> fieldList, String dataVersionField){
        if(StringUtils.isEmptyList(fieldList)){
            return false;
        }
        for(FieldInfo fi : fieldList){
            if(fi.getFieldName().equalsIgnoreCase(dataVersionField) && fi.getDataType().equalsIgnoreCase(FieldInfo.TYPE_LONG)){
                return true;
            }
        }
        return false;
    }
    
    public static void main(String[] args){
        
        String test1 = "123test";
        String test2 = "5690.2";
        String test3 = "598000";
        String test4 = "0";
        String test5 = "";
        
        long startTime = System.nanoTime();
        Class<?> clazz1 = StringUtils.getNumbericType(test1);
        System.out.println(test1 + " = " + clazz1.getName() + ", time = " + (System.nanoTime()-startTime));
        
        startTime = System.nanoTime();
        Class<?> clazz2 = StringUtils.getNumbericType(test2);
        System.out.println(test2 + " = " + clazz2.getName() + ", time = " + (System.nanoTime()-startTime));
        
        startTime = System.nanoTime();
        Class<?> clazz3 = StringUtils.getNumbericType(test3);
        System.out.println(test3 + " = " + clazz3.getSimpleName() + ", time = " + (System.nanoTime()-startTime));
        
        startTime = System.nanoTime();
        Class<?> clazz4 = StringUtils.getNumbericType(test4);
        System.out.println(test4 + " = " + clazz4.getTypeName() + ", time = " + (System.nanoTime()-startTime));
        
        startTime = System.nanoTime();
        Class<?> clazz5 = StringUtils.getNumbericType(test5);
        System.out.println(test5 + " = " + clazz5.getCanonicalName() + ", time = " + (System.nanoTime()-startTime));
    }
}