重写代码生成器支持模板(多层架构,MVC),多语言c#,java;支持mysql和sqlserver,动态编译

多年前用过李天平前辈的,自己改过,后来李老师做动软了,不给源码,修改不是很方便。加上我目前需要转java方向,于是决定自己搞。到目前为止花了整整一个星期了,看看目前的成果。

重写代码生成器支持模板(多层架构,MVC),多语言c#,java;支持mysql和sqlserver,动态编译_第1张图片

重写代码生成器支持模板(多层架构,MVC),多语言c#,java;支持mysql和sqlserver,动态编译_第2张图片

重写代码生成器支持模板(多层架构,MVC),多语言c#,java;支持mysql和sqlserver,动态编译_第3张图片

重写代码生成器支持模板(多层架构,MVC),多语言c#,java;支持mysql和sqlserver,动态编译_第4张图片

重写代码生成器支持模板(多层架构,MVC),多语言c#,java;支持mysql和sqlserver,动态编译_第5张图片

重写代码生成器支持模板(多层架构,MVC),多语言c#,java;支持mysql和sqlserver,动态编译_第6张图片

最后是代码工程文件,用c#开发的,IDE是vs2010

重写代码生成器支持模板(多层架构,MVC),多语言c#,java;支持mysql和sqlserver,动态编译_第7张图片

 

为了实现最大的模板自由,设计了专有的模板语法。基于C#,但是已经做到尽量简化,对有一点开发经验的同行应该是很好上手的。

目前c#的代码模板已经做了一些通用样例,接下来做java的开发代码模板。

总之,为了提高效率,并且规范项目团队成员的代码书写。

 

下面把核心的代码两个类文件贴出来,分别是动态编译和模板解析

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using System.CodeDom.Compiler;
  6 using System.Reflection;
  7 
  8 namespace CodeMaker.Engine
  9 {
 10     public class Compiler
 11     {
 12         /// <summary>
 13         /// 普通代码编译执行出字符串
 14         /// </summary>
 15         /// <param name="strCode"></param>
 16         /// <returns></returns>
 17         public static string DoCompile(string strCode)
 18         {
 19             
 20             StringBuilder strResults = new StringBuilder();
 21 
 22             CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");
 23 
 24             //CompilerParameters 编译参数
 25             CompilerParameters objCompilerParameters = new CompilerParameters();
 26             objCompilerParameters.ReferencedAssemblies.Add("System.dll");
 27             objCompilerParameters.ReferencedAssemblies.Add("System.Core.dll");
 28             objCompilerParameters.ReferencedAssemblies.Add("System.Data.dll");
 29             objCompilerParameters.ReferencedAssemblies.Add("CodeMaker.BLL.dll");
 30             objCompilerParameters.ReferencedAssemblies.Add("CodeMaker.DALFactory.dll");
 31             objCompilerParameters.ReferencedAssemblies.Add("CodeMaker.IDAL.dll");
 32             objCompilerParameters.ReferencedAssemblies.Add("CodeMaker.Model.dll");
 33             objCompilerParameters.ReferencedAssemblies.Add("CodeMaker.MySqlDAL.dll");
 34             objCompilerParameters.ReferencedAssemblies.Add("CodeMaker.SqlDAL.dll");
 35             objCompilerParameters.ReferencedAssemblies.Add("CodeMaker.Engine.dll");
 36             objCompilerParameters.GenerateExecutable = false;
 37             objCompilerParameters.GenerateInMemory = true;
 38             
 39             // CompilerResults
 40             CompilerResults cr = provider.CompileAssemblyFromSource(objCompilerParameters, strCode);
 41 
 42             if (cr.Errors.HasErrors)
 43             {
 44                 Console.WriteLine("编译错误:");
 45                 foreach (CompilerError err in cr.Errors)
 46                 {
 47                     strResults.Append(err.ErrorText);
 48                     strResults.Append(Environment.NewLine);
 49                     strResults.Append(err.Line);
 50                     strResults.Append(Environment.NewLine);
 51                     strResults.Append(err.ToString());
 52                     strResults.Append(Environment.NewLine);
 53                 
 54                 }
 55             }
 56             else
 57             {
 58                 // 通过反射,调用OutPut的输出方法
 59                 Assembly objAssembly = cr.CompiledAssembly;
 60                 object objHelloWorld = objAssembly.CreateInstance("DynamicCodeGenerate.CodeGenerate");
 61                 MethodInfo objMI = objHelloWorld.GetType().GetMethod("OutPut");
 62 
 63                 strResults.Append(objMI.Invoke(objHelloWorld, null));
 64                 strResults.Append(Environment.NewLine);
 65               
 66             }
 67             
 68             
 69             return strResults.ToString();
 70         }
 71 
 72         public static string DoCodeMakerCompile(string strDBType,string DALAssemblyPath, string strDataBase,string strTableName, string strEntityName,string strCode)
 73         {
 74             
 75             
 76             StringBuilder sb = new StringBuilder();
 77             //加上要编译部分代码的头部和尾部
 78             //头部
 79             sb.Append("using System;");
 80             sb.Append("using System.Data;");
 81             sb.Append("using System.Text;");
 82             sb.Append("using System.Linq;");
 83             sb.Append("using System.Globalization;");
 84             sb.Append("using System.Collections.Generic;");
 85             sb.Append("using CodeMaker.Model;");
 86             sb.Append("using CodeMaker.BLL;");
 87             sb.Append("using CodeMaker.Engine;");
 88             sb.Append("namespace DynamicCodeGenerate");
 89             sb.Append("{");
 90 
 91             
 92 
 93             sb.Append("   public class CodeGenerate");
 94             sb.Append("   {");
 95             sb.Append("        public string OutPut()");
 96             sb.Append("        {");
 97 
 98             //读取数据实体的属性的代码段
 99             sb.Append(GetEntity(strDBType, DALAssemblyPath, strDataBase, strTableName, strEntityName));
100 
101             sb.Append(strCode);
102 
103             //返回值,字符串
104             sb.Append("         return s.ToString(); ");
105             sb.Append("        }");
106             //fOutPut方法结束
107             //首字母大写方法
108             sb.Append("        public string ToTitleCase(string str)");
109             sb.Append("        {");
110             sb.Append("          return str.Substring(0,1).ToUpper()+str.Substring(1);");
111             sb.Append("        }");
112             //首字母小写方法
113             sb.Append("        public string ToLowerCase(string str)");
114             sb.Append("        {");
115             sb.Append("          return str.Substring(0,1).ToLower()+str.Substring(1);");
116             sb.Append("        }");
117             
118             sb.Append("   }");
119             sb.Append("}");
120 
121             return DoCompile(sb.ToString());
122         }
123 
124         private static string GetEntity(string strDBType, string DALAssemblyPath, string strDataBase, string strTableName, string strEntityName)
125         {
126             StringBuilder sb = new StringBuilder();
127             sb.Append("CodeMaker.BLL.EntityBLL bll = new CodeMaker.BLL.EntityBLL(\"" + DALAssemblyPath + "\");");
128             sb.Append("IList<CodeMaker.Model.Entity> es = bll.GetEntityList(\"" + strDataBase + "\", \"" + strTableName + "\");");
129             sb.Append("string EntityName=\"" + strEntityName + "\";");//实体名,供模板中的代码段使用
130             sb.Append("string TableName=\"" + strTableName + "\";");//表名,供模板中的代码段使用
131             sb.Append("string DBType=\"" + strDBType + "\";");//数据库组件,判断数据库种类SQLSERVER,MYSQL,供模板中的代码段使用
132             sb.Append("string TablePri=(es.Where(x=>x.IsPri==\"YES\").Count()>0)?es.Where(x=>x.IsPri==\"YES\").ToList()[0].ColumnName:\"\";");//表的主键列 名称
133             sb.Append("string TablePriDataType=(es.Where(x=>x.IsPri==\"YES\").Count()>0)?CodeAnalysis.ToDataTypeFormat(es.Where(x=>x.IsPri==\"YES\").ToList()[0].DataType,DBType):\"\";");//表的主键列 数据类型
134             return sb.ToString();
135            
136         }
137 
138         public static string GenerateCode()
139         {
140             return "";
141         }
142     }
143 }

 

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using System.Text.RegularExpressions;
  6 
  7 namespace CodeMaker.Engine
  8 {
  9     public class CodeAnalysis
 10     {
 11         public static string Hello()
 12         {
 13             return "Hello";
 14         }
 15 
 16         public static string ToCSharpCode(string strContent)
 17         {
 18             StringBuilder sb = new StringBuilder();
 19             //需要逐行解析
 20             string[] ss = strContent.Split('\n');
 21             string strT=string.Empty;
 22             if (ss.Length > 0)
 23             {
 24                 sb.Append("StringBuilder s = new StringBuilder();");//如果行数不为0,则需要声明字符串拼接
 25                 sb.Append(System.Environment.NewLine);
 26             }
 27             for (int i = 0; i < ss.Length; i++)
 28             {
 29                 //处理字符串行
 30                 sb.Append(DealCode(ss[i]));
 31                 sb.Append(System.Environment.NewLine);
 32               
 33 
 34             }
 35 
 36             return sb.ToString();
 37         }
 38 
 39         /// <summary>
 40         /// 单行字符串处理
 41         /// </summary>
 42         /// <param name="strLine"></param>
 43         /// <returns></returns>
 44         private static string DealCode(string strLine)
 45         {
 46             //判断当该行是无特殊代码行。特殊代码(<-$、$->)
 47 
 48             strLine = Regex.Replace(strLine, @"[\r\n]", "");  //替换掉常量中的换行符
 49            
 50            
 51             if (strLine.Contains("<-$") && strLine.Contains("$->"))
 52             {
 53                 //有整行特殊代码段
 54                 //strLine = strLine.Replace("\"", "\\\"");
 55                 strLine = strLine.Replace("<-$", "");
 56                 strLine = strLine.Replace("$->", "");
 57 
 58                 //strLine += "s.Append(System.Environment.NewLine);";
 59             }
 60             else if (strLine.Contains("<+$") && strLine.Contains("$+>"))
 61             {
 62                 //有变量取值代码段
 63                 strLine = strLine.Replace("\"", "\\\"");
 64                 strLine = "\""+strLine+"\\n\"";//前后先加引号,后面加个换行
 65                 strLine = strLine.Replace("<+$", "\"+");
 66                 strLine = strLine.Replace("$+>", "+\"");
 67                
 68                 
 69                 strLine = "s.Append("+ strLine +");";
 70             }
 71             else
 72             { 
 73                 //不是特殊代码行
 74                 //strLine = "s.Append(\"" + strLine + "\"); s.Append(System.Environment.NewLine);" ;
 75                 strLine = strLine.Replace("\"", "\\\"");
 76                 strLine = "s.Append(\"" + strLine + "\\n\");";
 77             }
 78 
 79             return strLine;
 80         }
 81 
 82         #region 供动态编译的代码段中调用的静态方法
 83 
 84         /// <summary>
 85         /// 数据库字段数据类型 转为 java语言中的数据类型
 86         /// </summary>
 87         /// <param name="strDBColumnType">数据库字段数据类型</param>
 88         /// <param name="strDBType">数据库MYSQL  SQLSERVER</param>
 89         /// <returns></returns>
 90         public static string ToJavaDataType(string strDBColumnType, string strDBType)
 91         {
 92             string strT = string.Empty;
 93 
 94             //根据strDBType 判断数据库是什么,然后转换为程序语言中的数据类型
 95             switch (strDBType)
 96             {
 97                 case "SQLSERVER":
 98                     var stringwords = new string[]{"char","varchar","text","nchar","nvarchar","ntext"};
 99                     var intwords = new string[]{"int","smallint","tinyint"};
100                     var boolwords = new string[] { "bit"};
101                     var longwords = new string[] { "bigint"};
102                     var decimalwords = new string[] { "numeric", "decimal", "money","smallmoney","float","real" };
103                     var datewords = new string[] { "datetime", "smalldatetime" };
104                     if (stringwords.Contains(strDBColumnType.ToLower()))
105                     { 
106                         strT="String";
107                     }
108                     else if (intwords.Contains(strDBColumnType.ToLower()))
109                     {
110                         strT = "int";
111                     }
112                     else if (longwords.Contains(strDBColumnType.ToLower()))
113                     {
114                         strT = "long";
115                     }
116                     else if (boolwords.Contains(strDBColumnType.ToLower()))
117                     {
118                         strT = "boolean";
119                     }
120                     else if (decimalwords.Contains(strDBColumnType.ToLower()))
121                     {
122                         strT = "decimal";
123                     }
124                     else if (datewords.Contains(strDBColumnType.ToLower()))
125                     {
126                         strT = "DateTime";
127                     }
128                     else
129                     {
130                         strT = "String";
131                     }
132 
133 
134                     break;
135 
136                 case "MYSQL":
137                      var stringwords1 = new string[]{"char","varchar","text","tinytext","mediumtext","longtext"};
138                     var intwords1 = new string[]{"smallint","tinyint","mediumint"};
139                     var boolwords1 = new string[] { "bit"};
140                     var longwords1 = new string[] { "int,bigint", "integer" };
141                     var decimalwords1 = new string[] { "float", "decimal", "double" };
142                     var datewords1 = new string[] { "datetime", "date" };
143                     if (stringwords1.Contains(strDBColumnType.ToLower()))
144                     {
145                         strT = "String";
146                     }
147                     else if (intwords1.Contains(strDBColumnType.ToLower()))
148                     {
149                         strT = "int";
150                     }
151                     else if (longwords1.Contains(strDBColumnType.ToLower()))
152                     {
153                         strT = "long";
154                     }
155                     else if (boolwords1.Contains(strDBColumnType.ToLower()))
156                     {
157                         strT = "boolean";
158                     }
159                     else if (decimalwords1.Contains(strDBColumnType.ToLower()))
160                     {
161                         strT = "decimal";
162                     }
163                     else if (datewords1.Contains(strDBColumnType.ToLower()))
164                     {
165                         strT = "DateTime";
166                     }
167                     else
168                     {
169                         strT = "String";
170                     }
171 
172 
173                     break;
174 
175                 default:
176                     break;
177             }
178 
179             return strT;
180         }
181 
182         /// <summary>
183         /// 数据库字段数据类型 转为 c# 语言中的数据类型
184         /// </summary>
185         /// <param name="strDBColumnType">数据库字段数据类型</param>
186         /// <param name="strDBType">数据库MYSQL  SQLSERVER</param>
187         /// <returns></returns>
188         public static string ToCSDataType(string strDBColumnType, string strDBType)
189         {
190             string strT = string.Empty;
191 
192             //根据strDBType 判断数据库是什么,然后转换为程序语言中的数据类型
193             switch (strDBType)
194             {
195                 case "SQLSERVER":
196                     var stringwords = new string[]{"char","varchar","text","nchar","nvarchar","ntext"};
197                     var intwords = new string[]{"int","smallint","tinyint"};
198                     var boolwords = new string[] { "bit"};
199                     var longwords = new string[] { "bigint"};
200                     var decimalwords = new string[] { "numeric", "decimal", "money","smallmoney","float","real" };
201                     var datewords = new string[] { "datetime", "smalldatetime" };
202                     if (stringwords.Contains(strDBColumnType.ToLower()))
203                     { 
204                         strT="string";
205                     }
206                     else if (intwords.Contains(strDBColumnType.ToLower()))
207                     {
208                         strT = "int";
209                     }
210                     else if (longwords.Contains(strDBColumnType.ToLower()))
211                     {
212                         strT = "long";
213                     }
214                     else if (boolwords.Contains(strDBColumnType.ToLower()))
215                     {
216                         strT = "bool";
217                     }
218                     else if (decimalwords.Contains(strDBColumnType.ToLower()))
219                     {
220                         strT = "decimal";
221                     }
222                     else if (datewords.Contains(strDBColumnType.ToLower()))
223                     {
224                         strT = "DateTime";
225                     }
226                     else
227                     {
228                         strT = "string";
229                     }
230 
231 
232                     break;
233 
234                 case "MYSQL":
235                      var stringwords1 = new string[]{"char","varchar","text","tinytext","mediumtext","longtext"};
236                     var intwords1 = new string[]{"smallint","tinyint","mediumint"};
237                     var boolwords1 = new string[] { "bit"};
238                     var longwords1 = new string[] { "int,bigint", "integer" };
239                     var decimalwords1 = new string[] { "float", "decimal", "double" };
240                     var datewords1 = new string[] { "datetime", "date" };
241                     if (stringwords1.Contains(strDBColumnType.ToLower()))
242                     { 
243                         strT="string";
244                     }
245                     else if (intwords1.Contains(strDBColumnType.ToLower()))
246                     {
247                         strT = "int";
248                     }
249                     else if (longwords1.Contains(strDBColumnType.ToLower()))
250                     {
251                         strT = "long";
252                     }
253                     else if (boolwords1.Contains(strDBColumnType.ToLower()))
254                     {
255                         strT = "bool";
256                     }
257                     else if (decimalwords1.Contains(strDBColumnType.ToLower()))
258                     {
259                         strT = "decimal";
260                     }
261                     else if (datewords1.Contains(strDBColumnType.ToLower()))
262                     {
263                         strT = "DateTime";
264                     }
265                     else
266                     {
267                         strT = "string";
268                     }
269 
270 
271                     break;
272 
273                 default:
274                     break;
275             }
276 
277             return strT;
278         }
279 
280         /// <summary>
281         /// 把小写的sqlserver数据库中的数据类型转为sqlserver参数格式,例如 SqlDbType.VarChar
282         /// </summary>
283         /// <param name="strDataType"></param>
284         /// <param name="strDBType">数据库MYSQL  SQLSERVER</param>
285         /// <returns></returns>
286         public static string ToDataTypeFormat(string strDataType,string strDBType)
287         {
288             string strT = string.Empty;
289             switch (strDataType.ToLower())
290             {
291                 case "int":
292                     strT = "Int";
293                     break;
294                 case "varchar":
295                     strT = "VarChar";
296                     break;
297                 case "char":
298                     strT = "Char";
299                     break;
300                 case "bigint":
301                     strT = "BigInt";
302                     break;
303                 case "nvarchar":
304                     strT = "NVarChar";
305                     break;
306                 case "datetime":
307                     strT = "DateTime";
308                     break;
309                 case "smalldatetime":
310                     strT = "SmallDateTime";
311                     break;
312                 case "bit":
313                     strT = "Bit";
314                     break;
315                 case "text":
316                     strT = "Text";
317 
318                     break;
319                     case "decimal":
320                     strT = "Decimal";
321                     break;
322                     case "ntext":
323                     strT = "NText";
324                     break;
325                 default:
326                     strT = "VarChar";
327                     break;
328             }
329 
330             return strT;
331         }
332 
333         /// <summary>
334         /// 获取数据类型或控件的简写,用于前缀命名
335         /// </summary>
336         /// <param name="strLongName"></param>
337         /// <returns></returns>
338         public static string ToNameFormat(string strLongName)
339         {
340             string strT = string.Empty;
341             switch (strLongName.ToLower())
342             {
343                 case "int":
344                     strT = "int";
345                     break;
346                 case "string":
347                     strT = "str";
348                     break;
349                 case "char":
350                     strT = "ch";
351                     break;
352                 case "long":
353                     strT = "long";
354                     break;
355                 case "float":
356                     strT = "float";
357                     break;
358                 case "datetime":
359                     strT = "date";
360                     break;
361                 case "double":
362                     strT = "double";
363                     break;
364                 case "bool":
365                     strT = "Is";
366                     break;
367                 case "decimal":
368                     strT = "dec";
369                     break;
370                 case "boolean":
371                     strT = "Is";
372                     break;
373                 default:
374                     strT = "x";
375                     break;
376             }
377 
378             return strT;
379         }
380         #endregion
381     }
382 }

 --------------------------------------------------------------------------

有位博友提到过T4模板,我也看了一点点,但是我考虑的是不单单生成c#代码,目标代码还要java,因为目前正在转java方向。为了灵活性,我觉得自己定义规则比较放心,也许这个想法不成熟,但是先试试吧

 

 

下载链接

http://www.cnblogs.com/allanyang/p/4702467.html

你可能感兴趣的:(重写代码生成器支持模板(多层架构,MVC),多语言c#,java;支持mysql和sqlserver,动态编译)