初始化提交
Showing
25 changed files
with
1760 additions
and
1 deletions
pom.xml
0 → 100644
1 | <project xmlns="http://maven.apache.org/POM/4.0.0" | ||
2 | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
3 | xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
4 | <modelVersion>4.0.0</modelVersion> | ||
5 | |||
6 | <groupId>com.black</groupId> | ||
7 | <artifactId>ddl-script-creator</artifactId> | ||
8 | <version>0.0.1-SNAPSHOT</version> | ||
9 | <build> | ||
10 | <plugins> | ||
11 | <plugin> | ||
12 | <groupId>org.apache.maven.plugins</groupId> | ||
13 | <artifactId>maven-compiler-plugin</artifactId> | ||
14 | <configuration> | ||
15 | <source>7</source> | ||
16 | <target>7</target> | ||
17 | </configuration> | ||
18 | </plugin> | ||
19 | </plugins> | ||
20 | </build> | ||
21 | <packaging>jar</packaging> | ||
22 | |||
23 | <name>ddl-script-creator</name> | ||
24 | <url>http://maven.apache.org</url> | ||
25 | |||
26 | <properties> | ||
27 | <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||
28 | </properties> | ||
29 | |||
30 | <dependencies> | ||
31 | <dependency> | ||
32 | <groupId>junit</groupId> | ||
33 | <artifactId>junit</artifactId> | ||
34 | <version>3.8.1</version> | ||
35 | <scope>test</scope> | ||
36 | </dependency> | ||
37 | <dependency> | ||
38 | <groupId>mysql</groupId> | ||
39 | <artifactId>mysql-connector-java</artifactId> | ||
40 | <version>8.0.27</version> | ||
41 | </dependency> | ||
42 | <dependency> | ||
43 | <groupId>com.oracle.database.jdbc</groupId> | ||
44 | <artifactId>ojdbc8</artifactId> | ||
45 | <version>19.3.0.0</version> | ||
46 | </dependency> | ||
47 | |||
48 | <!-- https://mvnrepository.com/artifact/cn.hutool/hutool-core --> | ||
49 | <dependency> | ||
50 | <groupId>cn.hutool</groupId> | ||
51 | <artifactId>hutool-core</artifactId> | ||
52 | <version>5.8.5</version> | ||
53 | </dependency> | ||
54 | </dependencies> | ||
55 | </project> |
1 | package com.seektruth.ddl.creator; | ||
2 | |||
3 | import com.seektruth.ddl.creator.collector.DatabaseMetaDataCollector; | ||
4 | import com.seektruth.ddl.creator.ddl.Database; | ||
5 | import com.seektruth.ddl.creator.metadata.DatabaseMetaDataInfo; | ||
6 | import com.seektruth.ddl.creator.transfer.Transfer; | ||
7 | |||
8 | /** | ||
9 | * DDL 脚本生成器 | ||
10 | * @author black | ||
11 | * | ||
12 | */ | ||
13 | public class DDLScriptCreator { | ||
14 | protected DatabaseMetaDataCollector collector; | ||
15 | protected Transfer transfer; | ||
16 | public DDLScriptCreator(DatabaseMetaDataCollector collector, Transfer transfer) { | ||
17 | this.collector = collector; | ||
18 | this.transfer = transfer; | ||
19 | } | ||
20 | protected String create() { | ||
21 | // 1.收集数据库元数据 | ||
22 | DatabaseMetaDataInfo metaDataInfo = collector.collect(); | ||
23 | // 2.将元数据转换为目标数据库信息 | ||
24 | Database database = transfer.transform(metaDataInfo); | ||
25 | // 3.生成目标数据库的 ddl 脚本 | ||
26 | return database.ddl(); | ||
27 | } | ||
28 | } |
1 | package com.seektruth.ddl.creator.collector; | ||
2 | |||
3 | import com.seektruth.ddl.creator.datasource.Datasource; | ||
4 | import com.seektruth.ddl.creator.metadata.*; | ||
5 | |||
6 | import java.sql.*; | ||
7 | import java.util.ArrayList; | ||
8 | import java.util.HashMap; | ||
9 | import java.util.List; | ||
10 | import java.util.Map; | ||
11 | |||
12 | /** | ||
13 | * 数据库元数据收集器 | ||
14 | * | ||
15 | * @author black | ||
16 | * | ||
17 | */ | ||
18 | public abstract class DatabaseMetaDataCollector { | ||
19 | |||
20 | // 数据源 | ||
21 | protected Datasource datasource; | ||
22 | |||
23 | public DatabaseMetaDataCollector(Datasource datasource) throws ClassNotFoundException { | ||
24 | this.datasource = datasource; | ||
25 | load(); | ||
26 | } | ||
27 | |||
28 | public DatabaseMetaDataInfo collect(){ | ||
29 | DatabaseMetaDataInfo databaseMetaDataInfo= new DatabaseMetaDataInfo(); | ||
30 | try(Connection connection = connect();){ | ||
31 | DatabaseMetaData metaData = connection.getMetaData(); | ||
32 | databaseMetaDataInfo.setTables(getTables(metaData)); | ||
33 | } catch (SQLException e) { | ||
34 | e.printStackTrace(); | ||
35 | } | ||
36 | return databaseMetaDataInfo; | ||
37 | } | ||
38 | |||
39 | private void load() throws ClassNotFoundException { | ||
40 | Class.forName(datasource.getDriverClass()); | ||
41 | } | ||
42 | |||
43 | public Connection connect() throws SQLException { | ||
44 | String url = datasource.getUrl(); | ||
45 | String username = datasource.getUsername(); | ||
46 | String password = datasource.getPassword(); | ||
47 | Connection connection = DriverManager.getConnection(url, username, password); | ||
48 | return connection; | ||
49 | } | ||
50 | |||
51 | public void disconnect(Connection connection) { | ||
52 | if (connection != null) { | ||
53 | try { | ||
54 | connection.close(); | ||
55 | } catch (SQLException e) { | ||
56 | e.printStackTrace(); | ||
57 | } | ||
58 | } | ||
59 | } | ||
60 | |||
61 | protected abstract List<TableInfo> getTables(DatabaseMetaData metaData); | ||
62 | |||
63 | // schemaPattern: 当数据源是 oracle,那么送用户名;当数据源是 mysql,那么送null | ||
64 | public List<TableInfo> getTables(DatabaseMetaData metaData, String databaseName, String schemaPattern ) throws SQLException { | ||
65 | ResultSet resultSet = metaData.getTables(databaseName,schemaPattern,null , new String[]{"TABLE"}); | ||
66 | List<TableInfo> tables = new ArrayList<TableInfo>(); | ||
67 | while (resultSet.next()) { | ||
68 | String catalog = resultSet.getString("TABLE_CAT"); | ||
69 | String schema = resultSet.getString("TABLE_SCHEM"); | ||
70 | String name = resultSet.getString("TABLE_NAME"); | ||
71 | String type = resultSet.getString("TABLE_TYPE");// "TABLE", "VIEW", "SYSTEM TABLE", "GLOBAL TEMPORARY", | ||
72 | // "LOCAL TEMPORARY", "ALIAS", "SYNONYM". | ||
73 | String comment = resultSet.getString("REMARKS"); | ||
74 | // String typeCatalog = resultSet.getString("TYPE_CAT"); | ||
75 | // String typeSchema = resultSet.getString("TYPE_SCHEM"); | ||
76 | // String typeName = resultSet.getString("TYPE_NAME"); | ||
77 | // resultSet.getString("SELF_REFERENCING_COL_NAME"); | ||
78 | // resultSet.getString("REF_GENERATION"); | ||
79 | TableInfo tableInfo = new TableInfo(); | ||
80 | tableInfo.setCatalog(catalog); | ||
81 | tableInfo.setComment(comment); | ||
82 | tableInfo.setName(name); | ||
83 | tableInfo.setSchema(schema); | ||
84 | tableInfo.setType(type); | ||
85 | // tableInfo.setTypeCatalog(typeCatalog); | ||
86 | // tableInfo.setTypeName(typeName); | ||
87 | // tableInfo.setTypeSchema(typeSchema); | ||
88 | tables.add(tableInfo); | ||
89 | } | ||
90 | return tables; | ||
91 | } | ||
92 | |||
93 | // 获取所有列 | ||
94 | public List<ColumnInfo> getColumns(DatabaseMetaData metaData, String schame, String table) throws SQLException { | ||
95 | ResultSet resultSet = metaData.getColumns(null, schame, table, null); | ||
96 | List<ColumnInfo> columns = new ArrayList<ColumnInfo>(); | ||
97 | while (resultSet.next()) { | ||
98 | String tableName = resultSet.getString("TABLE_NAME"); | ||
99 | String columnName = resultSet.getString("COLUMN_NAME"); | ||
100 | Integer dataType = resultSet.getInt("DATA_TYPE"); | ||
101 | String typeName = resultSet.getString("TYPE_NAME"); | ||
102 | Integer size = resultSet.getInt("COLUMN_SIZE"); | ||
103 | Integer digit = resultSet.getInt("DECIMAL_DIGITS");// 精度 | ||
104 | Integer radix = resultSet.getInt("NUM_PREC_RADIX");// 进制 10 或者 2 | ||
105 | Integer nullable = resultSet.getInt("NULLABLE");// columnNoNulls ,columnNullable ,columnNullableUnknown | ||
106 | String comment = resultSet.getString("REMARKS"); | ||
107 | String defaultValue = resultSet.getString("COLUMN_DEF");// 默认值 | ||
108 | Integer charTypeByteLength = resultSet.getInt("CHAR_OCTET_LENGTH");// char 类型列的最大字节数 | ||
109 | Integer position = resultSet.getInt("ORDINAL_POSITION");// 列序号 | ||
110 | String isNullable = resultSet.getString("IS_NULLABLE"); | ||
111 | String autoincrement = resultSet.getString("IS_AUTOINCREMENT");// YES,NO,空字符串 | ||
112 | String generatedColumn = resultSet.getString("IS_GENERATEDCOLUMN");// 是否虚拟列 | ||
113 | |||
114 | ColumnInfo columnInfo = new ColumnInfo(); | ||
115 | columnInfo.setTableName(table); | ||
116 | columnInfo.setAutoincrement(autoincrement); | ||
117 | columnInfo.setComment(comment); | ||
118 | columnInfo.setDecimalDigits(digit); | ||
119 | columnInfo.setDefaultValue(defaultValue); | ||
120 | columnInfo.setGeneratedcolumn(generatedColumn); | ||
121 | columnInfo.setIndex(position); | ||
122 | columnInfo.setIs_nullable(isNullable); | ||
123 | columnInfo.setName(columnName); | ||
124 | columnInfo.setNullable(nullable); | ||
125 | columnInfo.setRadix(radix); | ||
126 | columnInfo.setSize(size); | ||
127 | columnInfo.setTableName(tableName); | ||
128 | columnInfo.setType(dataType); | ||
129 | columnInfo.setTypeName(typeName); | ||
130 | columnInfo.setCharTypeMaxBytesNumber(charTypeByteLength); | ||
131 | columns.add(columnInfo); | ||
132 | } | ||
133 | return columns; | ||
134 | } | ||
135 | |||
136 | public PrimaryKeyInfo getPrimaryKeys(DatabaseMetaData metaData, String table) throws SQLException{ | ||
137 | ResultSet resultSet = metaData.getPrimaryKeys(null, null, table); | ||
138 | PrimaryKeyInfo pk = new PrimaryKeyInfo(); | ||
139 | Map<Short, String> columnsMap = new HashMap<>(); | ||
140 | pk.setTableName(table); | ||
141 | while(resultSet.next()) { | ||
142 | String tableName = resultSet.getString("TABLE_NAME");// 表名 | ||
143 | String columnName = resultSet.getString("COLUMN_NAME");// 列名 | ||
144 | Short keySeq = resultSet.getShort("KEY_SEQ");// 在主键中的位置 | ||
145 | String pkName = resultSet.getString("PK_NAME");// 主键索引名 | ||
146 | pk.setName(pkName); | ||
147 | if(columnsMap.containsKey(keySeq)) { | ||
148 | continue; | ||
149 | } | ||
150 | columnsMap.put(keySeq, columnName); | ||
151 | pk.addColumn(keySeq, columnName); | ||
152 | } | ||
153 | pk.sortColumn(); | ||
154 | return pk; | ||
155 | } | ||
156 | |||
157 | public List<IndexInfo> getIndexs(DatabaseMetaData metaData, String schame, String tableName) throws SQLException{ | ||
158 | ResultSet resultSet = metaData.getIndexInfo(null, schame, tableName, false, false); | ||
159 | List<IndexInfo> indexesIndexInfos = new ArrayList<>(); | ||
160 | Map<String, IndexInfo> indexes = new HashMap<String, IndexInfo>(); | ||
161 | while(resultSet.next()) { | ||
162 | // 1.TABLE_CAT String => table catalog (may be null) | ||
163 | // 2.TABLE_SCHEM String => table schema (may be null) | ||
164 | // 3.TABLE_NAME String => table name | ||
165 | // 4.NON_UNIQUE boolean => Can index values be non-unique. false when TYPE is tableIndexStatistic | ||
166 | // 5.INDEX_QUALIFIER String => index catalog (may be null); null when TYPE is tableIndexStatistic | ||
167 | // 6.INDEX_NAME String => index name; null when TYPE is tableIndexStatistic | ||
168 | // 7.TYPE short => index type: | ||
169 | // ◦ tableIndexStatistic - this identifies table statistics that are returned in conjuction with a table's index descriptions | ||
170 | // ◦ tableIndexClustered - this is a clustered index | ||
171 | // ◦ tableIndexHashed - this is a hashed index | ||
172 | // ◦ tableIndexOther - this is some other style of index | ||
173 | // | ||
174 | // 8.ORDINAL_POSITION short => column sequence number within index; zero when TYPE is tableIndexStatistic | ||
175 | // 9.COLUMN_NAME String => column name; null when TYPE is tableIndexStatistic | ||
176 | // 10.ASC_OR_DESC String => column sort sequence, "A" => ascending, "D" => descending, may be null if sort sequence is not supported; null when TYPE is tableIndexStatistic | ||
177 | // 11.CARDINALITY long => When TYPE is tableIndexStatistic, then this is the number of rows in the table; otherwise, it is the number of unique values in the index. | ||
178 | // 12.PAGES long => When TYPE is tableIndexStatisic then this is the number of pages used for the table, otherwise it is the number of pages used for the current index. | ||
179 | // 13.FILTER_CONDITION String => Filter condition, if any. (may be null) | ||
180 | |||
181 | String tableNam = resultSet.getString("TABLE_NAME");// 表名 | ||
182 | String columnName = resultSet.getString("COLUMN_NAME");// 列名 | ||
183 | Short ordinalPosition = resultSet.getShort("ORDINAL_POSITION");// 列在索引中的位置 | ||
184 | String indexName = resultSet.getString("INDEX_NAME");// 索引名 | ||
185 | Boolean nonUnique= resultSet.getBoolean("NON_UNIQUE");//是否非唯一 | ||
186 | String ascOrDesc = resultSet.getString("ASC_OR_DESC");// 正序还是倒序 | ||
187 | |||
188 | if("A".equals(ascOrDesc)) { | ||
189 | ascOrDesc = "asc"; | ||
190 | } | ||
191 | if("D".equals(ascOrDesc)) { | ||
192 | ascOrDesc = "desc"; | ||
193 | } | ||
194 | |||
195 | |||
196 | if("PRIMARY".equalsIgnoreCase(indexName)) { | ||
197 | // 跳过主键索引 | ||
198 | continue; | ||
199 | } | ||
200 | |||
201 | IndexInfo indexInfo = indexes.get(indexName); | ||
202 | if(indexInfo == null) { | ||
203 | indexInfo = new IndexInfo(); | ||
204 | indexes.put(indexName, indexInfo); | ||
205 | indexesIndexInfos.add(indexInfo); | ||
206 | } | ||
207 | indexInfo.setTableName(tableNam); | ||
208 | indexInfo.setName(indexName); | ||
209 | indexInfo.setNonUnique(nonUnique); | ||
210 | indexInfo.addColumn(ordinalPosition, columnName, ascOrDesc); | ||
211 | } | ||
212 | |||
213 | |||
214 | indexesIndexInfos.forEach((c)->{ | ||
215 | c.sortColumn(); | ||
216 | }); | ||
217 | return indexesIndexInfos; | ||
218 | } | ||
219 | } |
1 | package com.seektruth.ddl.creator.collector; | ||
2 | |||
3 | import com.seektruth.ddl.creator.datasource.Datasource; | ||
4 | import com.seektruth.ddl.creator.metadata.TableInfo; | ||
5 | |||
6 | import java.sql.DatabaseMetaData; | ||
7 | import java.sql.SQLException; | ||
8 | import java.util.List; | ||
9 | |||
10 | /** | ||
11 | * MySQL 数据库元数据收集器 | ||
12 | * @author black | ||
13 | * | ||
14 | */ | ||
15 | public class MySQLDatabaseMetaDataCollector extends DatabaseMetaDataCollector { | ||
16 | |||
17 | public MySQLDatabaseMetaDataCollector(Datasource datasource) throws ClassNotFoundException { | ||
18 | super(datasource); | ||
19 | } | ||
20 | |||
21 | @Override | ||
22 | protected List<TableInfo> getTables(DatabaseMetaData metaData) { | ||
23 | List<TableInfo> tablesInfos = null; | ||
24 | try { | ||
25 | tablesInfos = getTables(metaData, datasource.getDatabaseName(), null); | ||
26 | for (int i = 0; i < tablesInfos.size(); i++) { | ||
27 | TableInfo table =tablesInfos.get(i); | ||
28 | table.setColumns( getColumns(metaData, datasource.getDatabaseName(), table.getName())); | ||
29 | table.setPrimaryKey( getPrimaryKeys(metaData, table.getName())); | ||
30 | table.setIndexs( getIndexs(metaData, datasource.getDatabaseName(), table.getName())); | ||
31 | } | ||
32 | } catch (SQLException e) { | ||
33 | e.printStackTrace(); | ||
34 | } | ||
35 | return tablesInfos; | ||
36 | } | ||
37 | } |
1 | package com.seektruth.ddl.creator.datasource; | ||
2 | |||
3 | /** | ||
4 | * 数据源信息 | ||
5 | * @author black | ||
6 | */ | ||
7 | public class Datasource { | ||
8 | private String username; | ||
9 | private String password; | ||
10 | private String url; | ||
11 | private String driverClass; | ||
12 | private String databaseName; | ||
13 | public String getUsername() { | ||
14 | return username; | ||
15 | } | ||
16 | public void setUsername(String username) { | ||
17 | this.username = username; | ||
18 | } | ||
19 | public String getPassword() { | ||
20 | return password; | ||
21 | } | ||
22 | public void setPassword(String password) { | ||
23 | this.password = password; | ||
24 | } | ||
25 | public String getUrl() { | ||
26 | return url; | ||
27 | } | ||
28 | public void setUrl(String url) { | ||
29 | this.url = url; | ||
30 | } | ||
31 | public String getDriverClass() { | ||
32 | return driverClass; | ||
33 | } | ||
34 | public void setDriverClass(String driverClass) { | ||
35 | this.driverClass = driverClass; | ||
36 | } | ||
37 | public String getDatabaseName() { | ||
38 | return databaseName; | ||
39 | } | ||
40 | public void setDatabaseName(String databaseName) { | ||
41 | this.databaseName = databaseName; | ||
42 | } | ||
43 | |||
44 | } |
1 | package com.seektruth.ddl.creator.ddl.oracle; | ||
2 | |||
3 | import java.sql.JDBCType; | ||
4 | |||
5 | /** | ||
6 | * JDBC 类型与 Oracle 类型映射枚举 | ||
7 | * | ||
8 | * @author black | ||
9 | * | ||
10 | */ | ||
11 | public enum JdbcTypeOracleTypeMapperEnum { | ||
12 | BIT(JDBCType.BIT,"number"), | ||
13 | SMALLINT(JDBCType.SMALLINT,"number"), | ||
14 | TINYINT(JDBCType.TINYINT, "number"), | ||
15 | INTEGER(JDBCType.INTEGER, "number"), | ||
16 | BIGINT(JDBCType.BIGINT , "number"), | ||
17 | DECIMAL(JDBCType.DECIMAL,"number"), | ||
18 | DOUBLE(JDBCType.DOUBLE,"number"), | ||
19 | LONGVARCHAR(JDBCType.LONGVARCHAR, "clob"), | ||
20 | TIMESTAMP(JDBCType.TIMESTAMP, "timestamp"), | ||
21 | VARCHAR(JDBCType.VARCHAR,"varchar2"), | ||
22 | ; | ||
23 | JDBCType jdbcType; | ||
24 | |||
25 | String oracleType; | ||
26 | |||
27 | private JdbcTypeOracleTypeMapperEnum(JDBCType jdbcType, String oracleType) { | ||
28 | this.jdbcType = jdbcType; | ||
29 | this.oracleType = oracleType; | ||
30 | } | ||
31 | |||
32 | public JDBCType getJdbcType() { | ||
33 | return jdbcType; | ||
34 | } | ||
35 | |||
36 | public String getOracleType() { | ||
37 | return oracleType; | ||
38 | } | ||
39 | |||
40 | public static String getOracleType(JDBCType jdbcType) { | ||
41 | JdbcTypeOracleTypeMapperEnum e = get( jdbcType); | ||
42 | if(e == null ) { | ||
43 | return null; | ||
44 | }else { | ||
45 | return e.getOracleType(); | ||
46 | } | ||
47 | } | ||
48 | |||
49 | public static JdbcTypeOracleTypeMapperEnum get(JDBCType jdbcType) { | ||
50 | JdbcTypeOracleTypeMapperEnum[] jdbcTypeOracleTypeMapperEnums = JdbcTypeOracleTypeMapperEnum.values(); | ||
51 | for (int i = 0; i < jdbcTypeOracleTypeMapperEnums.length; i++) { | ||
52 | JdbcTypeOracleTypeMapperEnum e = jdbcTypeOracleTypeMapperEnums[i]; | ||
53 | if (e.jdbcType == jdbcType) { | ||
54 | return e; | ||
55 | } | ||
56 | } | ||
57 | return null; | ||
58 | } | ||
59 | } |
1 | package com.seektruth.ddl.creator.ddl.oracle; | ||
2 | |||
3 | /** | ||
4 | * oracle 列信息 | ||
5 | * @author black | ||
6 | * | ||
7 | */ | ||
8 | public class OracleColumn { | ||
9 | |||
10 | String tableName; | ||
11 | // 在表中的序号 | ||
12 | Integer seq; | ||
13 | |||
14 | String name; | ||
15 | |||
16 | String typeName; | ||
17 | |||
18 | String length; | ||
19 | |||
20 | String scale; | ||
21 | |||
22 | String defaultValue; | ||
23 | |||
24 | String comment; | ||
25 | |||
26 | Boolean nullable; | ||
27 | |||
28 | // 需要使用单独序列 | ||
29 | Boolean needSquence; | ||
30 | |||
31 | public String getTableName() { | ||
32 | return tableName; | ||
33 | } | ||
34 | |||
35 | public void setTableName(String tableName) { | ||
36 | this.tableName = tableName; | ||
37 | } | ||
38 | |||
39 | public Integer getSeq() { | ||
40 | return seq; | ||
41 | } | ||
42 | |||
43 | public void setSeq(Integer seq) { | ||
44 | this.seq = seq; | ||
45 | } | ||
46 | |||
47 | public String getName() { | ||
48 | return name; | ||
49 | } | ||
50 | |||
51 | public void setName(String name) { | ||
52 | this.name = name; | ||
53 | } | ||
54 | |||
55 | public String getTypeName() { | ||
56 | return typeName; | ||
57 | } | ||
58 | |||
59 | public void setTypeName(String typeName) { | ||
60 | this.typeName = typeName; | ||
61 | } | ||
62 | |||
63 | public String getLength() { | ||
64 | return length; | ||
65 | } | ||
66 | |||
67 | public void setLength(String length) { | ||
68 | this.length = length; | ||
69 | } | ||
70 | |||
71 | public String getScale() { | ||
72 | return scale; | ||
73 | } | ||
74 | |||
75 | public void setScale(String scale) { | ||
76 | this.scale = scale; | ||
77 | } | ||
78 | |||
79 | public String getDefaultValue() { | ||
80 | return defaultValue; | ||
81 | } | ||
82 | |||
83 | public void setDefaultValue(String defaultValue) { | ||
84 | this.defaultValue = defaultValue; | ||
85 | } | ||
86 | |||
87 | public String getComment() { | ||
88 | return comment; | ||
89 | } | ||
90 | |||
91 | public void setComment(String comment) { | ||
92 | this.comment = comment; | ||
93 | } | ||
94 | |||
95 | public Boolean getNullable() { | ||
96 | return nullable; | ||
97 | } | ||
98 | |||
99 | public void setNullable(Boolean nullable) { | ||
100 | this.nullable = nullable; | ||
101 | } | ||
102 | |||
103 | public Boolean getNeedSquence() { | ||
104 | return needSquence; | ||
105 | } | ||
106 | |||
107 | public void setNeedSquence(Boolean needSquence) { | ||
108 | this.needSquence = needSquence; | ||
109 | } | ||
110 | |||
111 | public OracleColumn() { | ||
112 | super(); | ||
113 | } | ||
114 | |||
115 | public String sql() { | ||
116 | StringBuffer buffer = new StringBuffer(); | ||
117 | buffer.append(" ").append(name).append(" "); | ||
118 | //System.out.println(tableName+", column :"+name+" typeName:" + typeName); | ||
119 | if(typeName.equals("number")) { | ||
120 | buffer.append(" ").append(typeName).append("("); | ||
121 | buffer.append(length); | ||
122 | if (scale != null) { | ||
123 | buffer.append(",").append(scale); | ||
124 | } | ||
125 | buffer.append(")").append(" "); | ||
126 | }else if(typeName.contains("varchar")) { | ||
127 | buffer.append(" ").append(typeName).append("("); | ||
128 | buffer.append(length); | ||
129 | buffer.append(")").append(" "); | ||
130 | }else if (typeName.equals("clob") || typeName.equals("timestamp")) { | ||
131 | buffer.append(" ").append(typeName).append(" "); | ||
132 | } | ||
133 | |||
134 | if (defaultValue != null) { | ||
135 | buffer.append("default ").append(defaultValue).append(" "); | ||
136 | } | ||
137 | |||
138 | if(!nullable) { | ||
139 | buffer.append("not null "); | ||
140 | } | ||
141 | |||
142 | return buffer.toString(); | ||
143 | } | ||
144 | |||
145 | public String comment() { | ||
146 | StringBuffer buffer = new StringBuffer(); | ||
147 | buffer.append(" comment on column ").append(tableName).append(".").append(name).append(" is "); | ||
148 | buffer.append("'").append(comment).append("';"); | ||
149 | return buffer.toString(); | ||
150 | } | ||
151 | } |
1 | package com.seektruth.ddl.creator.ddl.oracle; | ||
2 | |||
3 | import com.seektruth.ddl.creator.ddl.Database; | ||
4 | |||
5 | import java.util.ArrayList; | ||
6 | import java.util.List; | ||
7 | |||
8 | |||
9 | /** | ||
10 | * Oracle 数据库信息,可生成 oracle数据库的 DDL 脚本 | ||
11 | * @author black | ||
12 | * | ||
13 | */ | ||
14 | public class OracleDatabase extends Database { | ||
15 | // 数据库名 | ||
16 | String name; | ||
17 | // 表 | ||
18 | List<OracleTable> tables = new ArrayList<OracleTable>(); | ||
19 | // 序列 | ||
20 | List<OracleSequence> sequences = new ArrayList<OracleSequence>(); | ||
21 | |||
22 | public String getName() { | ||
23 | return name; | ||
24 | } | ||
25 | |||
26 | public void setName(String name) { | ||
27 | this.name = name; | ||
28 | } | ||
29 | |||
30 | public List<OracleTable> getTables() { | ||
31 | return tables; | ||
32 | } | ||
33 | |||
34 | public void setTables(List<OracleTable> tables) { | ||
35 | this.tables = tables; | ||
36 | } | ||
37 | |||
38 | public List<OracleSequence> getSequences() { | ||
39 | return sequences; | ||
40 | } | ||
41 | |||
42 | public void setSequences(List<OracleSequence> sequences) { | ||
43 | this.sequences = sequences; | ||
44 | } | ||
45 | |||
46 | public String ddl() { | ||
47 | StringBuffer buffer = new StringBuffer(); | ||
48 | for (int i = 0; i < tables.size(); i++) { | ||
49 | OracleTable table = tables.get(i); | ||
50 | buffer.append(table.ddl()); | ||
51 | buffer.append(table.comment()); | ||
52 | buffer.append("\n"); | ||
53 | } | ||
54 | |||
55 | for (int i = 0; i < sequences.size(); i++) { | ||
56 | OracleSequence sequence = sequences.get(i); | ||
57 | buffer.append(sequence.ddl()); | ||
58 | } | ||
59 | return buffer.toString(); | ||
60 | } | ||
61 | } |
1 | package com.seektruth.ddl.creator.ddl.oracle; | ||
2 | |||
3 | import java.util.ArrayList; | ||
4 | import java.util.List; | ||
5 | |||
6 | /** | ||
7 | * oracle 索引信息 | ||
8 | * @author black | ||
9 | * | ||
10 | */ | ||
11 | public class OracleIndex { | ||
12 | // 索引名 | ||
13 | String name; | ||
14 | // 表名 | ||
15 | String tableName; | ||
16 | // 唯一索引? | ||
17 | Boolean unique; | ||
18 | // 列 | ||
19 | List<String> columns = new ArrayList<String>(); | ||
20 | |||
21 | public String getName() { | ||
22 | return name; | ||
23 | } | ||
24 | |||
25 | public String getTableName() { | ||
26 | return tableName; | ||
27 | } | ||
28 | |||
29 | public List<String> getColumns() { | ||
30 | return columns; | ||
31 | } | ||
32 | |||
33 | public void setName(String name) { | ||
34 | this.name = name; | ||
35 | } | ||
36 | |||
37 | public void setTableName(String tableName) { | ||
38 | this.tableName = tableName; | ||
39 | } | ||
40 | |||
41 | public void addColumn(String column) { | ||
42 | this.columns.add(column); | ||
43 | } | ||
44 | |||
45 | public Boolean getUnique() { | ||
46 | return unique; | ||
47 | } | ||
48 | |||
49 | public void setUnique(Boolean unique) { | ||
50 | this.unique = unique; | ||
51 | } | ||
52 | |||
53 | public String ddl() { | ||
54 | // create unique index {indexName} on {tableName}({column1},{column2}) | ||
55 | StringBuffer buffer = new StringBuffer(); | ||
56 | buffer.append("create "); | ||
57 | |||
58 | if(unique) { | ||
59 | buffer.append("unique "); | ||
60 | } | ||
61 | buffer.append("index ").append(name).append(" on "); | ||
62 | buffer.append(tableName).append(" ("); | ||
63 | for (int i = 0; i < columns.size(); i++) { | ||
64 | String column = columns.get(i); | ||
65 | buffer.append(column); | ||
66 | if (i != (columns.size() - 1)) { | ||
67 | buffer.append(", "); | ||
68 | } | ||
69 | } | ||
70 | buffer.append(");\n"); | ||
71 | return buffer.toString(); | ||
72 | } | ||
73 | } |
1 | package com.seektruth.ddl.creator.ddl.oracle; | ||
2 | |||
3 | import java.util.List; | ||
4 | |||
5 | /** | ||
6 | * oracle主键信息 | ||
7 | * @author black | ||
8 | * | ||
9 | */ | ||
10 | public class OraclePrimaryKey { | ||
11 | // 主键 | ||
12 | String name; | ||
13 | // 表名 | ||
14 | String tableName; | ||
15 | // 列 | ||
16 | List<String> columns; | ||
17 | |||
18 | public String getName() { | ||
19 | return name; | ||
20 | } | ||
21 | |||
22 | public void setName(String name) { | ||
23 | this.name = name; | ||
24 | } | ||
25 | |||
26 | public String getTableName() { | ||
27 | return tableName; | ||
28 | } | ||
29 | |||
30 | public void setTableName(String tableName) { | ||
31 | this.tableName = tableName; | ||
32 | } | ||
33 | |||
34 | public List<String> getColumns() { | ||
35 | return columns; | ||
36 | } | ||
37 | |||
38 | public void setColumns(List<String> columns) { | ||
39 | this.columns = columns; | ||
40 | } | ||
41 | |||
42 | |||
43 | public String ddl() { | ||
44 | // alter table {table_a} add constraint {pkname} primary key ({column1},{column2}...); | ||
45 | StringBuffer buffer = new StringBuffer(); | ||
46 | buffer.append("alter table ").append(tableName).append(" add constraint "); | ||
47 | buffer.append(name).append(" primary key ("); | ||
48 | for (int i = 0; i < columns.size(); i++) { | ||
49 | String column = columns.get(i); | ||
50 | buffer.append(column); | ||
51 | if(i != (columns.size()-1) ) { | ||
52 | buffer.append(", "); | ||
53 | } | ||
54 | } | ||
55 | buffer.append(");\n"); | ||
56 | return buffer.toString(); | ||
57 | } | ||
58 | } |
1 | package com.seektruth.ddl.creator.ddl.oracle; | ||
2 | |||
3 | /** | ||
4 | * 序列信息 | ||
5 | * | ||
6 | * @author black | ||
7 | * | ||
8 | */ | ||
9 | public class OracleSequence { | ||
10 | |||
11 | String name; | ||
12 | |||
13 | String start; | ||
14 | |||
15 | String increment; | ||
16 | |||
17 | String maxvalue; | ||
18 | |||
19 | String minvalue; | ||
20 | |||
21 | Boolean cycle; | ||
22 | |||
23 | Boolean cache; | ||
24 | |||
25 | Integer cacheSize; | ||
26 | |||
27 | public String getName() { | ||
28 | return name; | ||
29 | } | ||
30 | |||
31 | public String getStart() { | ||
32 | return start; | ||
33 | } | ||
34 | |||
35 | public String getIncrement() { | ||
36 | return increment; | ||
37 | } | ||
38 | |||
39 | public String getMaxvalue() { | ||
40 | return maxvalue; | ||
41 | } | ||
42 | |||
43 | public String getMinvalue() { | ||
44 | return minvalue; | ||
45 | } | ||
46 | |||
47 | public Boolean getCycle() { | ||
48 | return cycle; | ||
49 | } | ||
50 | |||
51 | public Boolean getCache() { | ||
52 | return cache; | ||
53 | } | ||
54 | |||
55 | public Integer getCacheSize() { | ||
56 | return cacheSize; | ||
57 | } | ||
58 | |||
59 | public void setName(String name) { | ||
60 | this.name = name; | ||
61 | } | ||
62 | |||
63 | public void setStart(String start) { | ||
64 | this.start = start; | ||
65 | } | ||
66 | |||
67 | public void setIncrement(String increment) { | ||
68 | this.increment = increment; | ||
69 | } | ||
70 | |||
71 | public void setMaxvalue(String maxvalue) { | ||
72 | this.maxvalue = maxvalue; | ||
73 | } | ||
74 | |||
75 | public void setMinvalue(String minvalue) { | ||
76 | this.minvalue = minvalue; | ||
77 | } | ||
78 | |||
79 | public void setCycle(Boolean cycle) { | ||
80 | this.cycle = cycle; | ||
81 | } | ||
82 | |||
83 | public void setCache(Boolean cache) { | ||
84 | this.cache = cache; | ||
85 | } | ||
86 | |||
87 | public void setCacheSize(Integer cacheSize) { | ||
88 | this.cacheSize = cacheSize; | ||
89 | } | ||
90 | |||
91 | public String ddl() { | ||
92 | // create sequence {name} start with {1} increment by {1} minvalue {1} maxvalue {9999999} nocycle nocache; | ||
93 | StringBuffer buffer = new StringBuffer(); | ||
94 | buffer.append("create sequence ").append(name).append(" "); | ||
95 | buffer.append("start with ").append(start).append(" "); | ||
96 | buffer.append("increment by ").append(increment).append(" "); | ||
97 | buffer.append("minvalue ").append(minvalue).append(" "); | ||
98 | buffer.append("maxvalue ").append(maxvalue).append(" "); | ||
99 | if (cycle) { | ||
100 | buffer.append("cycle "); | ||
101 | } else { | ||
102 | buffer.append("nocycle "); | ||
103 | } | ||
104 | |||
105 | if (cache) { | ||
106 | buffer.append("cache ").append(cacheSize).append(" "); | ||
107 | } else { | ||
108 | buffer.append("nocache "); | ||
109 | } | ||
110 | |||
111 | buffer.append(";\n"); | ||
112 | return buffer.toString(); | ||
113 | } | ||
114 | } |
1 | package com.seektruth.ddl.creator.ddl.oracle; | ||
2 | |||
3 | import java.util.ArrayList; | ||
4 | import java.util.List; | ||
5 | |||
6 | /** | ||
7 | * oracle 表信息 | ||
8 | * @author black | ||
9 | * | ||
10 | */ | ||
11 | public class OracleTable { | ||
12 | // 表名 | ||
13 | String name; | ||
14 | // 主键 | ||
15 | OraclePrimaryKey primaryKey; | ||
16 | // 列 | ||
17 | List<OracleColumn> columns; | ||
18 | // 索引 | ||
19 | List<OracleIndex> indexs = new ArrayList<OracleIndex>(); | ||
20 | // 备注 | ||
21 | String commnet; | ||
22 | |||
23 | public String getName() { | ||
24 | return name; | ||
25 | } | ||
26 | |||
27 | public void setName(String name) { | ||
28 | this.name = name; | ||
29 | } | ||
30 | |||
31 | public OraclePrimaryKey getPrimaryKey() { | ||
32 | return primaryKey; | ||
33 | } | ||
34 | |||
35 | public void setPrimaryKey(OraclePrimaryKey primaryKey) { | ||
36 | this.primaryKey = primaryKey; | ||
37 | } | ||
38 | |||
39 | public List<OracleColumn> getColumns() { | ||
40 | return columns; | ||
41 | } | ||
42 | |||
43 | public void setColumns(List<OracleColumn> columns) { | ||
44 | this.columns = columns; | ||
45 | } | ||
46 | |||
47 | public List<OracleIndex> getIndexs() { | ||
48 | return indexs; | ||
49 | } | ||
50 | |||
51 | public void setIndexs(List<OracleIndex> indexs) { | ||
52 | this.indexs = indexs; | ||
53 | } | ||
54 | |||
55 | public String getCommnet() { | ||
56 | return commnet; | ||
57 | } | ||
58 | |||
59 | public void setCommnet(String commnet) { | ||
60 | this.commnet = commnet; | ||
61 | } | ||
62 | |||
63 | public String ddl() { | ||
64 | // create table tablename( column1 columnType ); | ||
65 | StringBuffer buffer = new StringBuffer(); | ||
66 | buffer.append("create table ").append(name).append("("); | ||
67 | for (int i = 0; i < columns.size(); i++) { | ||
68 | OracleColumn oracleColumn = columns.get(i); | ||
69 | buffer.append("\n\t"); | ||
70 | buffer.append(oracleColumn.sql()); | ||
71 | if(i != columns.size() -1) { | ||
72 | buffer.append(","); | ||
73 | } | ||
74 | } | ||
75 | buffer.append(");\n"); | ||
76 | // pk | ||
77 | if(primaryKey != null) { | ||
78 | buffer.append(primaryKey.ddl()); | ||
79 | } | ||
80 | // 索引 | ||
81 | for( int i = 0; i < indexs.size(); i++) { | ||
82 | OracleIndex index = indexs.get(i); | ||
83 | index.setName("idx_"+name+"_"+(i+1)); | ||
84 | buffer.append(index.ddl()); | ||
85 | } | ||
86 | return buffer.toString(); | ||
87 | } | ||
88 | |||
89 | public String comment() { | ||
90 | StringBuffer buffer = new StringBuffer(); | ||
91 | buffer.append(" comment on table ").append(name).append(" is "); | ||
92 | buffer.append("'").append(commnet).append("';"); | ||
93 | for (int i = 0; i < columns.size(); i++) { | ||
94 | OracleColumn oracleColumn = columns.get(i); | ||
95 | buffer.append("\n"); | ||
96 | buffer.append(oracleColumn.comment()); | ||
97 | } | ||
98 | return buffer.toString(); | ||
99 | } | ||
100 | } |
1 | package com.seektruth.ddl.creator.metadata; | ||
2 | |||
3 | /** | ||
4 | * 数据库元数据:表的列信息 | ||
5 | * @author black | ||
6 | * | ||
7 | */ | ||
8 | public class ColumnInfo { | ||
9 | |||
10 | private String tableName; | ||
11 | |||
12 | private String name; | ||
13 | // java.sql.Types | ||
14 | private Integer type; | ||
15 | |||
16 | private String typeName; | ||
17 | |||
18 | private Integer size; | ||
19 | |||
20 | private Integer decimalDigits; | ||
21 | |||
22 | // 进制 | ||
23 | private Integer radix; | ||
24 | |||
25 | private Integer nullable; | ||
26 | |||
27 | private String comment; | ||
28 | |||
29 | private String defaultValue; | ||
30 | // 序号 | ||
31 | private Integer index; | ||
32 | |||
33 | private String is_nullable; | ||
34 | // 是否自增 | ||
35 | private String autoincrement; | ||
36 | // 是否虚拟列 | ||
37 | private String generatedcolumn; | ||
38 | // char 类型的最大字节数量 | ||
39 | private Integer charTypeMaxBytesNumber; | ||
40 | |||
41 | public String getTableName() { | ||
42 | return tableName; | ||
43 | } | ||
44 | |||
45 | public void setTableName(String tableName) { | ||
46 | this.tableName = tableName; | ||
47 | } | ||
48 | |||
49 | public String getName() { | ||
50 | return name; | ||
51 | } | ||
52 | |||
53 | public void setName(String name) { | ||
54 | this.name = name; | ||
55 | } | ||
56 | |||
57 | public Integer getType() { | ||
58 | return type; | ||
59 | } | ||
60 | |||
61 | public void setType(Integer type) { | ||
62 | this.type = type; | ||
63 | } | ||
64 | |||
65 | public String getTypeName() { | ||
66 | return typeName; | ||
67 | } | ||
68 | |||
69 | public void setTypeName(String typeName) { | ||
70 | this.typeName = typeName; | ||
71 | } | ||
72 | |||
73 | public Integer getSize() { | ||
74 | return size; | ||
75 | } | ||
76 | |||
77 | public void setSize(Integer size) { | ||
78 | this.size = size; | ||
79 | } | ||
80 | |||
81 | public Integer getDecimalDigits() { | ||
82 | return decimalDigits; | ||
83 | } | ||
84 | |||
85 | public void setDecimalDigits(Integer decimalDigits) { | ||
86 | this.decimalDigits = decimalDigits; | ||
87 | } | ||
88 | |||
89 | public Integer getRadix() { | ||
90 | return radix; | ||
91 | } | ||
92 | |||
93 | public void setRadix(Integer radix) { | ||
94 | this.radix = radix; | ||
95 | } | ||
96 | |||
97 | public Integer getNullable() { | ||
98 | return nullable; | ||
99 | } | ||
100 | |||
101 | public void setNullable(Integer nullable) { | ||
102 | this.nullable = nullable; | ||
103 | } | ||
104 | |||
105 | public String getComment() { | ||
106 | return comment; | ||
107 | } | ||
108 | |||
109 | public void setComment(String comment) { | ||
110 | this.comment = comment; | ||
111 | } | ||
112 | |||
113 | public String getDefaultValue() { | ||
114 | return defaultValue; | ||
115 | } | ||
116 | |||
117 | public void setDefaultValue(String defaultValue) { | ||
118 | this.defaultValue = defaultValue; | ||
119 | } | ||
120 | |||
121 | public Integer getIndex() { | ||
122 | return index; | ||
123 | } | ||
124 | |||
125 | public void setIndex(Integer index) { | ||
126 | this.index = index; | ||
127 | } | ||
128 | |||
129 | public String getIs_nullable() { | ||
130 | return is_nullable; | ||
131 | } | ||
132 | |||
133 | public void setIs_nullable(String is_nullable) { | ||
134 | this.is_nullable = is_nullable; | ||
135 | } | ||
136 | |||
137 | public String getAutoincrement() { | ||
138 | return autoincrement; | ||
139 | } | ||
140 | |||
141 | public void setAutoincrement(String autoincrement) { | ||
142 | this.autoincrement = autoincrement; | ||
143 | } | ||
144 | |||
145 | public String getGeneratedcolumn() { | ||
146 | return generatedcolumn; | ||
147 | } | ||
148 | |||
149 | public void setGeneratedcolumn(String generatedcolumn) { | ||
150 | this.generatedcolumn = generatedcolumn; | ||
151 | } | ||
152 | |||
153 | public Integer getCharTypeMaxBytesNumber() { | ||
154 | return charTypeMaxBytesNumber; | ||
155 | } | ||
156 | |||
157 | public void setCharTypeMaxBytesNumber(Integer charTypeMaxBytesNumber) { | ||
158 | this.charTypeMaxBytesNumber = charTypeMaxBytesNumber; | ||
159 | } | ||
160 | |||
161 | @Override | ||
162 | public String toString() { | ||
163 | return "ColumnInfo [tableName=" + tableName + ", name=" + name + ", type=" + type + ", typeName=" + typeName | ||
164 | + ", size=" + size + ", decimalDigits=" + decimalDigits + ", radix=" + radix + ", nullable=" + nullable | ||
165 | + ", comment=" + comment + ", defaultValue=" + defaultValue + ", index=" + index + ", is_nullable=" | ||
166 | + is_nullable + ", autoincrement=" + autoincrement + ", generatedcolumn=" + generatedcolumn | ||
167 | + ", charTypeMaxBytesNumber=" + charTypeMaxBytesNumber + "]"; | ||
168 | } | ||
169 | |||
170 | |||
171 | } |
1 | package com.seektruth.ddl.creator.metadata; | ||
2 | |||
3 | import java.util.List; | ||
4 | |||
5 | /** | ||
6 | * 数据库元数据 | ||
7 | * | ||
8 | * @author black | ||
9 | * | ||
10 | */ | ||
11 | public class DatabaseMetaDataInfo { | ||
12 | |||
13 | private List<TableInfo> tables; | ||
14 | |||
15 | public List<TableInfo> getTables() { | ||
16 | return tables; | ||
17 | } | ||
18 | |||
19 | public void setTables(List<TableInfo> tables) { | ||
20 | this.tables = tables; | ||
21 | } | ||
22 | |||
23 | } |
1 | package com.seektruth.ddl.creator.metadata; | ||
2 | |||
3 | import java.util.Comparator; | ||
4 | /** | ||
5 | * 列下标比较器,用于索引中列排序 | ||
6 | * @author black | ||
7 | * | ||
8 | */ | ||
9 | public class IndexColumnComparator implements Comparator<IndexColumnInfo> { | ||
10 | |||
11 | @Override | ||
12 | public int compare(IndexColumnInfo o1, IndexColumnInfo o2) { | ||
13 | if (o1.getSeq() == o2.getSeq()) { | ||
14 | return 0; | ||
15 | } else if (o1.getSeq() > o2.getSeq()) { | ||
16 | return 1; | ||
17 | } else { | ||
18 | return -1; | ||
19 | } | ||
20 | } | ||
21 | |||
22 | } |
1 | package com.seektruth.ddl.creator.metadata; | ||
2 | |||
3 | /** | ||
4 | * 数据库元数据:索引关联列信息 | ||
5 | * @author black | ||
6 | * | ||
7 | */ | ||
8 | public class IndexColumnInfo { | ||
9 | // 索引中此列的位置 | ||
10 | Short seq; | ||
11 | // 列名 | ||
12 | String name; | ||
13 | // 排序 | ||
14 | String ascOrDesc; | ||
15 | |||
16 | public Short getSeq() { | ||
17 | return seq; | ||
18 | } | ||
19 | public void setSeq(Short seq) { | ||
20 | this.seq = seq; | ||
21 | } | ||
22 | public String getName() { | ||
23 | return name; | ||
24 | } | ||
25 | public void setName(String name) { | ||
26 | this.name = name; | ||
27 | } | ||
28 | |||
29 | public String getAscOrDesc() { | ||
30 | return ascOrDesc; | ||
31 | } | ||
32 | public void setAscOrDesc(String ascOrDesc) { | ||
33 | this.ascOrDesc = ascOrDesc; | ||
34 | } | ||
35 | @Override | ||
36 | public String toString() { | ||
37 | return "IndexColumnInfo [seq=" + seq + ", name=" + name + ", ascOrDesc=" + ascOrDesc + "]"; | ||
38 | } | ||
39 | |||
40 | } |
1 | package com.seektruth.ddl.creator.metadata; | ||
2 | |||
3 | import java.util.ArrayList; | ||
4 | import java.util.Collections; | ||
5 | import java.util.List; | ||
6 | import java.util.function.Predicate; | ||
7 | |||
8 | /** | ||
9 | * 数据库元数据:索引信息 | ||
10 | * @author black | ||
11 | * | ||
12 | */ | ||
13 | public class IndexInfo { | ||
14 | |||
15 | private String tableName; | ||
16 | |||
17 | private String name; | ||
18 | |||
19 | private Boolean nonUnique; | ||
20 | |||
21 | private List<IndexColumnInfo> columns = new ArrayList<IndexColumnInfo>(); | ||
22 | |||
23 | public String getTableName() { | ||
24 | return tableName; | ||
25 | } | ||
26 | |||
27 | public void setTableName(String tableName) { | ||
28 | this.tableName = tableName; | ||
29 | } | ||
30 | |||
31 | public String getName() { | ||
32 | return name; | ||
33 | } | ||
34 | |||
35 | public void setName(String name) { | ||
36 | this.name = name; | ||
37 | } | ||
38 | |||
39 | public Boolean getNonUnique() { | ||
40 | return nonUnique; | ||
41 | } | ||
42 | |||
43 | public void setNonUnique(Boolean nonUnique) { | ||
44 | this.nonUnique = nonUnique; | ||
45 | } | ||
46 | |||
47 | public List<IndexColumnInfo> getColumns() { | ||
48 | return columns; | ||
49 | } | ||
50 | |||
51 | public void addColumn(Short seq, String name, String ascOrDesc) { | ||
52 | boolean hasThisColumn = columns.stream().anyMatch(new Predicate<IndexColumnInfo>() { | ||
53 | @Override | ||
54 | public boolean test(IndexColumnInfo t) { | ||
55 | if(t.getSeq() == seq) { | ||
56 | return true; | ||
57 | } | ||
58 | return false; | ||
59 | }; | ||
60 | }); | ||
61 | if(hasThisColumn) { | ||
62 | return ; | ||
63 | } | ||
64 | IndexColumnInfo columnInfo = new IndexColumnInfo(); | ||
65 | columnInfo.setName(name); | ||
66 | columnInfo.setSeq(seq); | ||
67 | columnInfo.setAscOrDesc(ascOrDesc); | ||
68 | columns.add(columnInfo); | ||
69 | } | ||
70 | |||
71 | public void sortColumn() { | ||
72 | Collections.sort(columns, new IndexColumnComparator()); | ||
73 | } | ||
74 | |||
75 | @Override | ||
76 | public String toString() { | ||
77 | return "IndexInfo [tableName=" + tableName + ", name=" + name + ", columns=" + columns + "]"; | ||
78 | } | ||
79 | |||
80 | } |
1 | package com.seektruth.ddl.creator.metadata; | ||
2 | |||
3 | import java.util.ArrayList; | ||
4 | import java.util.Collections; | ||
5 | import java.util.List; | ||
6 | /** | ||
7 | * 数据库元数据:主键信息 | ||
8 | * @author black | ||
9 | * | ||
10 | */ | ||
11 | public class PrimaryKeyInfo { | ||
12 | |||
13 | private String tableName; | ||
14 | |||
15 | private String name; | ||
16 | |||
17 | private List<IndexColumnInfo> columns = new ArrayList<IndexColumnInfo>(); | ||
18 | |||
19 | public String getTableName() { | ||
20 | return tableName; | ||
21 | } | ||
22 | |||
23 | public void setTableName(String tableName) { | ||
24 | this.tableName = tableName; | ||
25 | } | ||
26 | |||
27 | public String getName() { | ||
28 | return name; | ||
29 | } | ||
30 | |||
31 | public void setName(String name) { | ||
32 | this.name = name; | ||
33 | } | ||
34 | public void addColumn(Short seq, String column) { | ||
35 | IndexColumnInfo indexColumnInfo= new IndexColumnInfo(); | ||
36 | indexColumnInfo.setSeq(seq); | ||
37 | indexColumnInfo.setName(column); | ||
38 | columns.add(indexColumnInfo); | ||
39 | } | ||
40 | |||
41 | public void sortColumn() { | ||
42 | Collections.sort(columns, new IndexColumnComparator()); | ||
43 | } | ||
44 | |||
45 | @Override | ||
46 | public String toString() { | ||
47 | return "PrimaryKeyInfo [tableName=" + tableName + ", name=" + name + ", columns=" + columns + "]"; | ||
48 | } | ||
49 | |||
50 | public List<IndexColumnInfo> getColumns() { | ||
51 | return columns; | ||
52 | } | ||
53 | |||
54 | } |
1 | package com.seektruth.ddl.creator.metadata; | ||
2 | |||
3 | import java.util.List; | ||
4 | |||
5 | /** | ||
6 | * 数据库元数据:表信息 | ||
7 | * @author black | ||
8 | * | ||
9 | */ | ||
10 | public class TableInfo { | ||
11 | |||
12 | private String catalog; | ||
13 | |||
14 | private String schema ; | ||
15 | // 表名 | ||
16 | private String name ; | ||
17 | |||
18 | private String type ; | ||
19 | // 表注释 | ||
20 | private String comment ; | ||
21 | |||
22 | private String typeCatalog; | ||
23 | |||
24 | private String typeSchema; | ||
25 | |||
26 | private String typeName ; | ||
27 | // 主键信息 | ||
28 | private PrimaryKeyInfo primaryKey; | ||
29 | // 索引信息 | ||
30 | private List<IndexInfo> indexs; | ||
31 | // 列信息 | ||
32 | private List<ColumnInfo> columns; | ||
33 | |||
34 | public String getCatalog() { | ||
35 | return catalog; | ||
36 | } | ||
37 | |||
38 | public void setCatalog(String catalog) { | ||
39 | this.catalog = catalog; | ||
40 | } | ||
41 | |||
42 | public String getSchema() { | ||
43 | return schema; | ||
44 | } | ||
45 | |||
46 | public void setSchema(String schema) { | ||
47 | this.schema = schema; | ||
48 | } | ||
49 | |||
50 | public String getName() { | ||
51 | return name; | ||
52 | } | ||
53 | |||
54 | public void setName(String name) { | ||
55 | this.name = name; | ||
56 | } | ||
57 | |||
58 | public String getType() { | ||
59 | return type; | ||
60 | } | ||
61 | |||
62 | public void setType(String type) { | ||
63 | this.type = type; | ||
64 | } | ||
65 | |||
66 | public String getComment() { | ||
67 | return comment; | ||
68 | } | ||
69 | |||
70 | public void setComment(String comment) { | ||
71 | this.comment = comment; | ||
72 | } | ||
73 | |||
74 | public String getTypeCatalog() { | ||
75 | return typeCatalog; | ||
76 | } | ||
77 | |||
78 | public void setTypeCatalog(String typeCatalog) { | ||
79 | this.typeCatalog = typeCatalog; | ||
80 | } | ||
81 | |||
82 | public String getTypeSchema() { | ||
83 | return typeSchema; | ||
84 | } | ||
85 | |||
86 | public void setTypeSchema(String typeSchema) { | ||
87 | this.typeSchema = typeSchema; | ||
88 | } | ||
89 | |||
90 | public String getTypeName() { | ||
91 | return typeName; | ||
92 | } | ||
93 | |||
94 | public void setTypeName(String typeName) { | ||
95 | this.typeName = typeName; | ||
96 | } | ||
97 | |||
98 | public PrimaryKeyInfo getPrimaryKey() { | ||
99 | return primaryKey; | ||
100 | } | ||
101 | |||
102 | public List<IndexInfo> getIndexs() { | ||
103 | return indexs; | ||
104 | } | ||
105 | |||
106 | public void setPrimaryKey(PrimaryKeyInfo primaryKey) { | ||
107 | this.primaryKey = primaryKey; | ||
108 | } | ||
109 | |||
110 | public void setIndexs(List<IndexInfo> indexs) { | ||
111 | this.indexs = indexs; | ||
112 | } | ||
113 | |||
114 | public List<ColumnInfo> getColumns() { | ||
115 | return columns; | ||
116 | } | ||
117 | |||
118 | public void setColumns(List<ColumnInfo> columns) { | ||
119 | this.columns = columns; | ||
120 | } | ||
121 | |||
122 | @Override | ||
123 | public String toString() { | ||
124 | return "TableInfo [catalog=" + catalog + ", schema=" + schema + ", name=" + name + ", type=" + type | ||
125 | + ", comment=" + comment + ", typeCatalog=" + typeCatalog + ", typeSchema=" + typeSchema + ", typeName=" | ||
126 | + typeName + "]"; | ||
127 | } | ||
128 | |||
129 | } |
1 | package com.seektruth.ddl.creator.transfer; | ||
2 | |||
3 | import com.seektruth.ddl.creator.ddl.oracle.*; | ||
4 | import com.seektruth.ddl.creator.metadata.*; | ||
5 | |||
6 | import java.sql.JDBCType; | ||
7 | import java.util.ArrayList; | ||
8 | import java.util.List; | ||
9 | |||
10 | |||
11 | /** | ||
12 | * 将数据库元数据转换为 Oracle 数据库信息 | ||
13 | * @author black | ||
14 | * | ||
15 | */ | ||
16 | public class OracleTransfer implements Transfer<OracleDatabase> { | ||
17 | |||
18 | @Override | ||
19 | public OracleDatabase transform(DatabaseMetaDataInfo metadata) { | ||
20 | OracleDatabase database = new OracleDatabase(); | ||
21 | List<OracleTable> tables = database.getTables(); | ||
22 | List<TableInfo> originTableInfos = metadata.getTables(); | ||
23 | originTableInfos.forEach((tableInfo) -> { | ||
24 | OracleTable table = new OracleTable(); | ||
25 | transformTable(tableInfo, table); | ||
26 | tables.add(table); | ||
27 | |||
28 | List<ColumnInfo> originColumnInfos = tableInfo.getColumns(); | ||
29 | List<OracleColumn> columns = new ArrayList<OracleColumn>(); | ||
30 | originColumnInfos.forEach((columnInfo) -> { | ||
31 | OracleColumn column = new OracleColumn(); | ||
32 | transformColumn(columnInfo, column); | ||
33 | columns.add(column); | ||
34 | }); | ||
35 | table.setColumns(columns); | ||
36 | |||
37 | // 主键索引 | ||
38 | PrimaryKeyInfo orignTablePrimaryKey = tableInfo.getPrimaryKey(); | ||
39 | if (orignTablePrimaryKey.getName() != null) { | ||
40 | OraclePrimaryKey key = new OraclePrimaryKey(); | ||
41 | transformPk(orignTablePrimaryKey, key); | ||
42 | table.setPrimaryKey(key); | ||
43 | } | ||
44 | // 索引 | ||
45 | List<IndexInfo> orignIndexInfos = tableInfo.getIndexs(); | ||
46 | if (orignIndexInfos != null && orignIndexInfos.size() > 0) { | ||
47 | final List<OracleIndex> oracleIndexs = table.getIndexs(); | ||
48 | orignIndexInfos.forEach((indexInfo) -> { | ||
49 | OracleIndex index = new OracleIndex(); | ||
50 | transformIndex(indexInfo, index); | ||
51 | oracleIndexs.add(index); | ||
52 | }); | ||
53 | } | ||
54 | // 生成序列 为自增列生成序列 | ||
55 | List<OracleSequence> oracleSequences = database.getSequences(); | ||
56 | OraclePrimaryKey tablePrimaryKey = table.getPrimaryKey(); | ||
57 | for (int j = 0; j < columns.size(); j++) { | ||
58 | OracleColumn c = columns.get(j); | ||
59 | OracleSequence sequence = null; | ||
60 | // 判断是否主键列 | ||
61 | boolean isPkColumn = false; | ||
62 | if (tablePrimaryKey != null && tablePrimaryKey.getColumns().get(0) != null) { | ||
63 | if (c.getName().equalsIgnoreCase(tablePrimaryKey.getColumns().get(0))) { | ||
64 | isPkColumn = true; | ||
65 | } | ||
66 | } | ||
67 | |||
68 | // 需要自增 | ||
69 | if (c.getNeedSquence()) { | ||
70 | if (isPkColumn) { | ||
71 | // 主键列的序列命名:"表名_SEQ" | ||
72 | sequence = createSequence(c.getLength(), table.getName() + "_SEQ"); | ||
73 | } else { | ||
74 | // 非主键列的序列命名:"表名_字段名_SEQ" | ||
75 | sequence = createSequence(c.getLength(), | ||
76 | table.getName() + "_" + columns.get(j).getName() + "_SEQ"); | ||
77 | } | ||
78 | } | ||
79 | if(sequence != null) { | ||
80 | oracleSequences.add(sequence); | ||
81 | } | ||
82 | } | ||
83 | }); | ||
84 | return database; | ||
85 | |||
86 | } | ||
87 | |||
88 | public void transformTable(TableInfo tableInfo, OracleTable table) { | ||
89 | table.setName(tableInfo.getName()); | ||
90 | table.setCommnet(tableInfo.getComment()); | ||
91 | } | ||
92 | |||
93 | public void transformColumn(ColumnInfo columnInfo, OracleColumn column) { | ||
94 | column.setComment(columnInfo.getComment()); | ||
95 | column.setDefaultValue(columnInfo.getDefaultValue()); | ||
96 | column.setLength(String.valueOf(columnInfo.getSize())); | ||
97 | column.setName(columnInfo.getName()); | ||
98 | column.setScale(String.valueOf(columnInfo.getDecimalDigits())); | ||
99 | column.setSeq(columnInfo.getIndex()); | ||
100 | column.setTableName(columnInfo.getTableName()); | ||
101 | // 需要进行类型转换 JdbcTYpe 转 oracle type | ||
102 | JDBCType jdbcType = JDBCType.valueOf(columnInfo.getType()); | ||
103 | column.setTypeName(JdbcTypeOracleTypeMapperEnum.getOracleType(jdbcType)); | ||
104 | |||
105 | if (columnInfo.getNullable() != null) { | ||
106 | column.setNullable(columnInfo.getNullable() == 0 ? false : true); | ||
107 | } | ||
108 | |||
109 | if ("YES".equals(columnInfo.getAutoincrement())) { | ||
110 | // 自增需要序列 | ||
111 | column.setNeedSquence(true); | ||
112 | } else { | ||
113 | column.setNeedSquence(false); | ||
114 | } | ||
115 | } | ||
116 | |||
117 | public void transformPk(PrimaryKeyInfo orignTablePrimaryKey,OraclePrimaryKey key) { | ||
118 | key.setName("pk_" + orignTablePrimaryKey.getTableName()); | ||
119 | key.setTableName(orignTablePrimaryKey.getTableName()); | ||
120 | List<IndexColumnInfo> orignTablePrimaryKeyColumns = orignTablePrimaryKey.getColumns(); | ||
121 | List<String> columnsList = new ArrayList<>(orignTablePrimaryKeyColumns.size()); | ||
122 | for (int j = 0; j < orignTablePrimaryKeyColumns.size(); j++) { | ||
123 | columnsList.add(orignTablePrimaryKeyColumns.get(j).getName()); | ||
124 | } | ||
125 | key.setColumns(columnsList); | ||
126 | } | ||
127 | |||
128 | public void transformIndex(IndexInfo indexInfo ,OracleIndex index) { | ||
129 | index.setName(indexInfo.getName()); | ||
130 | index.setTableName(indexInfo.getTableName()); | ||
131 | index.setUnique(!indexInfo.getNonUnique()); | ||
132 | |||
133 | List<IndexColumnInfo> orignTableIndexColumns = indexInfo.getColumns(); | ||
134 | for (int j = 0; j < orignTableIndexColumns.size(); j++) { | ||
135 | IndexColumnInfo indexColumnInfo = orignTableIndexColumns.get(j); | ||
136 | index.addColumn(indexColumnInfo.getName() + " " + indexColumnInfo.getAscOrDesc()); | ||
137 | } | ||
138 | } | ||
139 | |||
140 | // 创建序列 | ||
141 | public OracleSequence createSequence(String columnLength, String name) { | ||
142 | OracleSequence sequence = new OracleSequence(); | ||
143 | sequence.setCache(true); | ||
144 | sequence.setCacheSize(20); | ||
145 | sequence.setCycle(false); | ||
146 | sequence.setIncrement("1"); | ||
147 | sequence.setMinvalue("1"); | ||
148 | sequence.setMaxvalue(sequenceMaxValue(columnLength)); | ||
149 | sequence.setName(name); | ||
150 | sequence.setStart("1"); | ||
151 | return sequence; | ||
152 | } | ||
153 | |||
154 | private String sequenceMaxValue(String length) { | ||
155 | String maxValue = ""; | ||
156 | Integer lengthInteger = Integer.parseInt(length); | ||
157 | for (int i = 0; i < lengthInteger; i++) { | ||
158 | maxValue = maxValue + "9"; | ||
159 | } | ||
160 | return maxValue; | ||
161 | } | ||
162 | } |
1 | package com.seektruth.ddl.creator.transfer; | ||
2 | |||
3 | import com.seektruth.ddl.creator.ddl.Database; | ||
4 | import com.seektruth.ddl.creator.metadata.DatabaseMetaDataInfo; | ||
5 | |||
6 | /** | ||
7 | * 转换器 | ||
8 | * @author black | ||
9 | * | ||
10 | */ | ||
11 | public interface Transfer<T extends Database> { | ||
12 | T transform(DatabaseMetaDataInfo metadata); | ||
13 | } |
1 | package com.seektruth.ddl.creator; | ||
2 | |||
3 | |||
4 | import com.seektruth.ddl.creator.collector.DatabaseMetaDataCollector; | ||
5 | import com.seektruth.ddl.creator.collector.MySQLDatabaseMetaDataCollector; | ||
6 | import com.seektruth.ddl.creator.datasource.Datasource; | ||
7 | import com.seektruth.ddl.creator.transfer.OracleTransfer; | ||
8 | import com.seektruth.ddl.creator.transfer.Transfer; | ||
9 | |||
10 | public class DDLScriptCreatorTest { | ||
11 | |||
12 | public static void main(String[] args) throws ClassNotFoundException { | ||
13 | Datasource datasource = mysql(); | ||
14 | DatabaseMetaDataCollector collector = new MySQLDatabaseMetaDataCollector(datasource); | ||
15 | Transfer transfer = new OracleTransfer(); | ||
16 | DDLScriptCreator creater = new DDLScriptCreator(collector, transfer); | ||
17 | System.out.println(creater.create()); | ||
18 | } | ||
19 | |||
20 | public static Datasource oracle() { | ||
21 | String devUrl="jdbc:oracle:thin:@localhost:1521:orcl?useInformationSchema=true"; | ||
22 | String userName="dev_poc_rec"; | ||
23 | String password="black"; | ||
24 | Datasource datasource = new Datasource(); | ||
25 | datasource.setDriverClass("oracle.jdbc.driver.OracleDriver"); | ||
26 | datasource.setUrl(devUrl); | ||
27 | datasource.setUsername(userName); | ||
28 | datasource.setPassword(password); | ||
29 | datasource.setDatabaseName("orcl"); | ||
30 | return datasource; | ||
31 | } | ||
32 | public static Datasource mysql() { | ||
33 | //pedantic=true& | ||
34 | String devUrl="jdbc:mysql://rm-2zen60zh797n662w4lo.mysql.rds.aliyuncs.com:3306/dev_poc_rec?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useInformationSchema=true&nullDatabaseMeansCurrent=true"; | ||
35 | String userName="dev_poc_rec"; | ||
36 | String password="HMTWBekcV116aZfoy18Au4"; | ||
37 | |||
38 | // String devUrl="jdbc:mysql://rm-2zen60zh797n662w4lo.mysql.rds.aliyuncs.com:3306/standard_bank_test?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useInformationSchema=true&nullDatabaseMeansCurrent=true"; | ||
39 | // String userName="standard_bank_ts"; | ||
40 | // String password="cnX%Dio16YIKEWvt&UOdH"; | ||
41 | // String devUrl="jdbc:mysql://rm-2zen60zh797n662w4lo.mysql.rds.aliyuncs.com:3306/poc-rec-bank?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useInformationSchema=true&nullDatabaseMeansCurrent=true"; | ||
42 | // String userName="poc_rec_bank"; | ||
43 | // String password="f$FwIdm16Lp192qt014UT6o"; | ||
44 | Datasource datasource = new Datasource(); | ||
45 | datasource.setDriverClass("com.mysql.cj.jdbc.Driver"); | ||
46 | datasource.setUrl(devUrl); | ||
47 | datasource.setUsername(userName); | ||
48 | datasource.setPassword(password); | ||
49 | datasource.setDatabaseName("dev_poc_rec"); | ||
50 | return datasource; | ||
51 | } | ||
52 | } |
逻辑图.png
0 → 100644

15.4 KB
-
Please register or sign in to post a comment