1616package com .yanglb .utilitys .codegen .core .translator .impl ;
1717
1818import java .io .File ;
19+ import java .util .ArrayList ;
20+ import java .util .HashMap ;
21+ import java .util .List ;
1922
2023import com .yanglb .utilitys .codegen .core .model .DdlDetail ;
2124import com .yanglb .utilitys .codegen .core .model .DdlModel ;
2831
2932/**
3033 * MySQL 的DDL生成翻译器(单文件)
34+ *
3135 * @author yanglibing
3236 */
3337public class DdlMysqlTranslatorImpl extends BaseDdlTranslator {
@@ -36,39 +40,39 @@ public DdlMysqlTranslatorImpl() {
3640 this .sqlColumnStart = "`" ;
3741 this .sqlColumnEnd = "`" ;
3842 }
39-
43+
4044 @ Override
4145 protected void onBeforeTranslate () throws CodeGenException {
4246 super .onBeforeTranslate ();
4347 this .writableModel .setExtension ("ddl" );
4448 this .writableModel .setFilePath ("ddl_mysql" );
4549 this .writableModel .setLang (SupportLang .sql );
46-
50+
4751 // 设置文件名(同Excel名)
4852 String fileName = this .model .get (0 ).getExcelFileName ();
4953 File file = new File (fileName );
5054 fileName = file .getName ();
51-
55+
5256 int index = fileName .lastIndexOf ("." );
53- if (index != -1 ) {
57+ if (index != -1 ) {
5458 fileName = fileName .substring (0 , index );
5559 }
5660 this .writableModel .setFileName (fileName );
5761 }
5862
5963 @ Override
6064 protected void onTranslate () throws CodeGenException {
61- super .onTranslate ();
65+ super .onTranslate ();
6266 StringBuilder sb = this .writableModel .getData ();
63-
67+
6468 // 添加文件头
6569 sb .append (this .settingMap .get ("head" ));
66-
70+
6771 // 逐个添加内容
68- for (DdlModel itm : this .model ) {
72+ for (DdlModel itm : this .model ) {
6973 sb .append (this .genDdl (itm ));
7074 }
71-
75+
7276 // 添加外键
7377 sb .append (this .genForeignKey ());
7478 }
@@ -78,163 +82,225 @@ protected void onTranslate() throws CodeGenException {
7882 */
7983 @ Override
8084 protected Object getReplaceModel () {
81- if (this .model == null || this .model .size () <= 0 ) return null ;
82-
85+ if (this .model == null || this .model .size () <= 0 )
86+ return null ;
87+
8388 // 只使用第一个Sheet替换
8489 return this .model .get (0 );
8590 }
8691
8792 /**
8893 * 生成MySQL的DDL
89- * @param model 原始数据
94+ *
95+ * @param model
96+ * 原始数据
9097 * @return 生成结果
91- * @throws CodeGenException 出错信息
98+ * @throws CodeGenException
99+ * 出错信息
92100 */
93- public String genDdl (DdlModel model )
94- throws CodeGenException {
101+ public String genDdl (DdlModel model ) throws CodeGenException {
95102 StringBuilder sb = new StringBuilder ();
96103
104+ // 主键、约束、索引等
97105 String primaryKey = "" ;
98- // 表名
106+ HashMap <String , List <DdlDetail >> indexMap = new HashMap <String , List <DdlDetail >>();
107+ HashMap <String , List <DdlDetail >> uniqueMap = new HashMap <String , List <DdlDetail >>();
108+
109+ // 表名
99110 String tableName = this .genFullTableName (model );
100111 sb .append (String .format ("-- %s \r \n " , model .getSheetName ()));
101- sb .append (String .format ("-- %s \r \n " , model .getVersion ()));
112+ sb .append (String .format ("-- version %s \r \n " , model .getVersion ()));
102113 sb .append (String .format ("CREATE TABLE %s (\r \n " , tableName ));
103-
114+
104115 Integer autoIncrement = null ;
105- for (DdlDetail detail :model .getDetail ()) {
106- if (detail .isColKey ()) {
107- if (!StringUtility .isNullOrEmpty (primaryKey )) {
116+ for (DdlDetail detail : model .getDetail ()) {
117+ // 主键
118+ if (detail .isColKey ()) {
119+ if (!StringUtility .isNullOrEmpty (primaryKey )) {
108120 primaryKey += ", " ;
109121 }
110- primaryKey += String .format ("%s%s%s" ,
111- this .sqlColumnStart ,
112- detail .getColName (),
113- this .sqlColumnEnd );
122+ primaryKey += String .format ("%s%s%s" , this .sqlColumnStart ,
123+ detail .getColName (), this .sqlColumnEnd );
114124 }
115-
125+
116126 // 自增初始值
117- if (detail .getColAutoIncrement () != null ) autoIncrement = detail .getColAutoIncrement ();
127+ if (detail .getColAutoIncrement () != null )
128+ autoIncrement = detail .getColAutoIncrement ();
129+
130+ // 索引
131+ this .updateIndexUniqueMap (indexMap , detail .getColIndex (), detail );
132+
133+ // 约束
134+ this .updateIndexUniqueMap (uniqueMap , detail .getColUnique (), detail );
118135
136+ // 列明细
119137 sb .append (this .genDdlDetail (detail ));
120138 }
121-
139+
122140 // 主键
123- if (!StringUtility .isNullOrEmpty (primaryKey )) {
141+ if (!StringUtility .isNullOrEmpty (primaryKey )) {
124142 sb .append (String .format (" PRIMARY KEY (%s),\r \n " , primaryKey ));
125143 }
126144
127- // 删除最后一个 ,号
128- sb .deleteCharAt (sb .lastIndexOf ("," ));
129- sb .append (")\r \n " );
145+ // 索引
146+ if (!indexMap .isEmpty ()) {
147+ for (List <DdlDetail > list : indexMap .values ()) {
148+ sb .append (String .format (" %s,\r \n " , this .indexUniqueSql (list , true )));
149+ }
150+ }
130151
152+ // 约束
153+ if (!uniqueMap .isEmpty ()) {
154+ for (List <DdlDetail > list : uniqueMap .values ()) {
155+ sb .append (String .format (" %s,\r \n " , this .indexUniqueSql (list , false )));
156+ }
157+ }
158+
159+ // 删除最后一个 ,号
160+ sb .deleteCharAt (sb .lastIndexOf ("," ));
161+
131162 // 引擎、字符集等其它信息
132- sb .append ("ENGINE={my_sql_engine}\r \n " );
133- sb .append ("DEFAULT CHARSET={my_sql_defaultCharSet}\r \n " );
163+ StringBuilder info = new StringBuilder ();
164+ info .append ("ENGINE={my_sql_engine} " );
165+ info .append ("DEFAULT CHARSET={my_sql_defaultCharSet} " );
134166 if (autoIncrement != null ) {
135- sb .append ("AUTO_INCREMENT=" + autoIncrement );
167+ info .append (String . format ( "AUTO_INCREMENT=%d " , autoIncrement ) );
136168 }
137-
169+
138170 // 结束
139- sb .append ("; \r \n \r \n " );
140-
171+ sb .append (String . format ( ") %s; \r \n \r \n ", info . toString (). trim ()) );
172+
141173 return sb .toString ();
142174 }
143175
176+ private void updateIndexUniqueMap (HashMap <String , List <DdlDetail >> map , String names , DdlDetail detail ) {
177+ if (!StringUtility .isNullOrEmpty (names )) {
178+ String [] keys = names .split ("," );
179+ for (String key : keys ) {
180+ key = key .trim ();
181+ List <DdlDetail > value = map .get (key );
182+ if (value == null ) {
183+ value = new ArrayList <DdlDetail >();
184+ map .put (key , value );
185+ }
186+
187+ value .add (detail );
188+ }
189+ }
190+ }
191+
192+ private String indexUniqueSql (List <DdlDetail > list , boolean isIndex ) {
193+ String name = "" ;
194+ StringBuilder sb = new StringBuilder ();
195+ for (DdlDetail detail : list ) {
196+ name += detail .getColName () + "_" ;
197+
198+ sb .append (String .format ("%s%s%s ASC, " , this .sqlColumnStart ,
199+ detail .getColName (), this .sqlColumnEnd ));
200+ }
201+
202+ // 名字加后缀
203+ name += isIndex ? "INDEX" :"UNIQUE" ;
204+ sb .deleteCharAt (sb .lastIndexOf ("," ));
205+
206+ String result = String .format ("%s %s(%s)" , isIndex ? "INDEX" :"UNIQUE INDEX" , name , sb .toString ());
207+ return result ;
208+ }
209+
144210 private String genDdlDetail (DdlDetail detail ) {
145211 StringBuilder sb = new StringBuilder ();
146212 String type = detail .getColType ();
147- if (detail .getColLength () != null ) {
148- if (detail .getColPrecision () != null ) {
213+ if (detail .getColLength () != null ) {
214+ if (detail .getColPrecision () != null ) {
149215 // 长度及精度都有 NUMBER(10,2)
150- type = String .format ("%s(%d, %d)" , type
151- , detail .getColLength ().intValue ()
152- , detail .getColPrecision ().intValue ());
216+ type = String .format ("%s(%d, %d)" , type , detail .getColLength ()
217+ .intValue (), detail .getColPrecision ().intValue ());
153218 } else {
154219 // 只有长度 VARCHAR2(10)
155- type = String .format ("%s(%d)" , type
156- , detail . getColLength () .intValue ());
220+ type = String .format ("%s(%d)" , type , detail . getColLength ()
221+ .intValue ());
157222 }
158223 } else {
159224 // 暂时忽略这种情况
160- if (detail .getColPrecision () == null ) {
225+ if (detail .getColPrecision () == null ) {
161226 // 长度及精度都没有 VARCHAR
162227 } else {
163228 // 只有精度 NUMBER(2,2) ? 错误?
164229 }
165230 }
166- sb .append (String .format (" %s%s%s %s"
167- ,this .sqlColumnStart
168- ,detail .getColName ()
169- ,this .sqlColumnEnd
170- ,type ));
171-
172- if (!detail .isColNullable ()) {
231+ sb .append (String .format (" %s%s%s %s" , this .sqlColumnStart ,
232+ detail .getColName (), this .sqlColumnEnd , type ));
233+
234+ if (!detail .isColNullable ()) {
173235 sb .append (" NOT NULL" );
174236 }
175-
237+
176238 // 自增长列
177- if (detail .getColAutoIncrement () != null ) {
239+ if (detail .getColAutoIncrement () != null ) {
178240 sb .append (" AUTO_INCREMENT" );
179241 }
180-
181- // TODO: 默认值还有问题
182- if (!StringUtility .isNullOrEmpty (detail .getColDefault ())) {
183- sb .append (String .format (" DEFAULT '%s'" , detail .getColDefault ()));
242+
243+ // 默认值、只有text/char 需要加引号
244+ if (!StringUtility .isNullOrEmpty (detail .getColDefault ())) {
245+ String colType = detail .getColType ().toLowerCase ();
246+ if (colType .contains ("text" ) || colType .contains ("char" )) {
247+ sb .append (String .format (" DEFAULT '%s'" , detail .getColDefault ()));
248+ } else {
249+ sb .append (String .format (" DEFAULT %s" , detail .getColDefault ()));
250+ }
184251 }
185-
186- sb .append (",\r \n " );
252+
253+ sb .append (",\r \n " );
187254 return sb .toString ();
188255 }
189-
256+
190257 /**
191258 * 添加外键
259+ *
192260 * @throws CodeGenException
193261 */
194262 private String genForeignKey () throws CodeGenException {
195263 StringBuilder sb = new StringBuilder ();
196- if (this .foreignKeyList .size ()> 0 ) {
264+ if (this .foreignKeyList .size () > 0 ) {
197265 sb .append ("\r \n " );
198- sb .append ("-- ----------------------------- --\r \n " );
266+ sb .append ("-- -------------------------------\r \n " );
199267 sb .append ("-- foreign key list\r \n " );
200- sb .append ("-- ----------------------------- --\r \n " );
268+ sb .append ("-- -------------------------------\r \n " );
201269 }
202-
270+
203271 // 所有表的外键放在最后处理
204- for (ForeignModel model : this .foreignKeyList ) {
272+ for (ForeignModel model : this .foreignKeyList ) {
205273 // 取得主、外键的列名
206- String columnName = "" ,referenceColumnName = "" ;
207-
208- for (ForeignDetailModel foreignColumns : model .getForeignColumns ()) {
209- if (!StringUtility .isNullOrEmpty (columnName )) {
210- columnName += ", " ;
274+ String columnName = "" , referenceColumnName = "" ;
275+
276+ for (ForeignDetailModel foreignColumns : model .getForeignColumns ()) {
277+ if (!StringUtility .isNullOrEmpty (columnName )) {
278+ columnName += ", " ;
211279 }
212- if (!StringUtility .isNullOrEmpty (referenceColumnName )) {
280+ if (!StringUtility .isNullOrEmpty (referenceColumnName )) {
213281 referenceColumnName += ", " ;
214282 }
215-
283+
216284 // 外键列,如:[AddressBizId], [AddressRev]
217- columnName += String .format ("%s%s%s" ,
218- this .sqlColumnStart ,
285+ columnName += String .format ("%s%s%s" , this .sqlColumnStart ,
219286 foreignColumns .getDdlDetail ().getColName (),
220287 this .sqlColumnEnd );
221-
288+
222289 // 主键列,如:[BizId], [Rev]
223- referenceColumnName += String .format ("%s%s%s" ,
224- this .sqlColumnStart ,
225- foreignColumns .getForeignDdlDetail ().getColName (),
290+ referenceColumnName += String .format ("%s%s%s" ,
291+ this .sqlColumnStart , foreignColumns
292+ .getForeignDdlDetail ().getColName (),
226293 this .sqlColumnEnd );
227294 }
228-
295+
229296 // 表名
230297 String tableName = genFullTableName (model .getDdlModel ());
231- String referenceTableName = genFullTableName (model .getForeignColumns ().get (0 ).getForeignDdlModel ());
298+ String referenceTableName = genFullTableName (model
299+ .getForeignColumns ().get (0 ).getForeignDdlModel ());
232300 sb .append (String .format ("ALTER TABLE %s ADD FOREIGN KEY(%s) \r \n "
233301 + "REFERENCES %s (%s) \r \n "
234302 + "ON DELETE CASCADE ON UPDATE CASCADE; \r \n \r \n " ,
235- tableName ,
236- columnName ,
237- referenceTableName ,
303+ tableName , columnName , referenceTableName ,
238304 referenceColumnName ));
239305 }
240306 return sb .toString ();
0 commit comments