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


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

    QQ图片20150729212121

    QQ截图20150729212205

    QQ截图20150729213325

    QQ截图20150729213412

    QQ截图20150729213436

    QQ截图20150729213529

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

    QQ截图20150729214011

    为了实现最大的模板自由,设计了专有的模板语法。基于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('
    ');
     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, @"[
    ]", "");  //替换掉常量中的换行符
     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

  • 相关阅读:
    Linux基本权限管理
    Spring JMS
    消息中间件 ActiveMQ的简单使用
    Ionic slides 轮播图
    Spring 3 MVC and XML example
    Java 数组
    Java String类
    Java static 使用
    http://blog.csdn.net/huang_xw/article/details/7090173
    http://blog.chinaunix.net/uid-20577907-id-3519578.html
  • 原文地址:https://www.cnblogs.com/allanyang/p/4687534.html
Copyright © 2020-2023  润新知