zoukankan      html  css  js  c++  java
  • 代码自动生成工具MyGeneration之一

      前段时间用C#做网站,用到了大量数据库相关的东西。网站采用3层结构,即数据访问层(Data Access Layer),业务逻辑层(Business Logic Layer),页面表现层().做了一段时间,发现向数据访问层和业务逻辑层加入新的类,数据库的表结构改了,还要对应的修改数据访问层和业务逻辑层的代码,这个工作很是繁琐,无聊,而且容易出错。做了几次之后就想有什么办法可以让机器自动完成呢?

      联想到以前看过Java似乎有个Hibernate,可以很方便的实现对象关系映射(ORM),即自动的从数据库的表生成对应的对象,.Net也应该有类似的功能吧。于是找啊找,发现了很多.Net的ORM工具,不过都有缺点,就是代码得依赖于那些ORM工具,我希望能够让机器按我的要求生成我自己的代码,这样就更加灵活了。

      于是乎,发现了CodeSmith和MyGeneration,CodeSmith是 网上传的.NET 程序员十种必备工具之一,我们写代码时,经常需要重复完成某些特定的任务,例如编写数据访问代码或者生成自定义集合。我们可以用CodeSmith编写模板自动完成这些任务,从而不仅提高工作效率,而且能够自动完成那些最为乏味的任务。可惜,CodeSmith是需要注册的,试用版只能用15天。而MyGeneration基本上和CodeSmith的功能差不多哦,但是他是开源的。我选软件的原则是能开源免费的就用,实在没替代了才选那些需要注册的,有版权的软件。所以就选MyGeneration了。

      用过一段时间后感觉MyGeneration主要是为了自动生成数据库相关的代码的,可能C#用得比较多,其实我们可以用它生成任何代码,C++,JavaScript...而且还不仅仅局限于数据库,其他方面的代码也可以用MyGeneration自动生成。比如我们经常用数据访问层和业务逻辑层,用MyGeneration就可以自动生成这些代码,我们可以不用手动写代码了。比如数据访问层,我们需要调用一个存储过程,用MyGeneration我们只需要选择生成存储过程代码的模板,执行一下脚本,然后在界面上选择数据库上某个存储过程,然后就自动生成了数据库访问代码,整个过程只需要点几下鼠标,代码就自动生成了。这对于需要大量操作数据库的程序员来说,效率是多大的提升啊。

    废话少说,还是来点实在的吧。首先声明,我的MyGeneration版本是:1.3.0.3

    安装完MyGeneration后,第一次启动会要求进行一些数据库相关的配置。如图:

    ConnectionString: 就是指定连接哪个数据库了,填好这个就可以点确定了。

    下面来看一看其他的项都是什么。

    Language Mapping:就是指定数据库和对象基本类型的映射关系。让我们打开Languages.xml文件看一下吧:

     1     <Language From="SQL" To="C#">
     2         <Type From="bigint" To="long" />
     3         <Type From="binary" To="object" />
     4         <Type From="bit" To="bool" />
     5         <Type From="char" To="string" />
     6         <Type From="datetime" To="DateTime" />
     7         <Type From="decimal" To="decimal" />
     8         <Type From="float" To="double" />
     9         <Type From="image" To="byte[]" />
    10         <Type From="int" To="int" />
    11         <Type From="money" To="decimal" />
    12         <Type From="nchar" To="string" />
    13         <Type From="ntext" To="string" />
    14         <Type From="numeric" To="decimal" />
    15         <Type From="nvarchar" To="string" />
    16         <Type From="real" To="float" />
    17         <Type From="smalldatetime" To="DateTime" />
    18         <Type From="smallint" To="short" />
    19         <Type From="smallmoney" To="decimal" />
    20         <Type From="text" To="string" />
    21         <Type From="timestamp" To="byte[]" />
    22         <Type From="tinyint" To="byte" />
    23         <Type From="uniqueidentifier" To="Guid" />
    24         <Type From="varbinary" To="byte[]" />
    25         <Type From="varchar" To="string" />
    26         <Type From="xml" To="string" />
    27         <Type From="sql_variant" To="object" />
    28     </Language>

    这是里面的一段内容,很明显,是数据库SQL的字段转到C#是什么类型,里面没有C++的,假如我们要让它支持C++的话,需要在这里加入SQL到C++的类型转换。

    Database Target Mapping:先看里面的内容吧:

     1     <DbTarget From="ACCESS" To="DAO">
     2         <Type From="Text" To="DAO.dbText" />
     3         <Type From="Memo" To="DAO.dbMemo" />
     4         <Type From="DateTime" To="DAO.dbDate" />
     5         <Type From="Currency" To="DAO.dbCurrency" />
     6         <Type From="Yes/No" To="DAO.dbBoolean" />
     7         <Type From="OLE Object" To="DAO.dbLongBinary" />
     8         <Type From="Hyperlink" To="DAO.dbMemo" />
     9         <Type From="Double" To="DAO.dbDouble" />
    10         <Type From="Replication ID" To="DAO.dbGUID" />
    11         <Type From="Long" To="DAO.dbLong" />
    12         <Type From="Single" To="DAO.dbSingle" />
    13         <Type From="Decimal" To="DAO.dbDecimal" />
    14         <Type From="Byte" To="DAO.dbByte" />
    15         <Type From="Integer" To="DAO.dbInteger" />
    16     </DbTarget>

    呵呵,一目了然,就是Access数据库用DAO的方式访问,数据库的列的类型对应的DAO里是什么类型。

    UseMetaData目前没什么用。

    看看MyGeneration的界面吧:

    先让我们体验一下吧。

    展开Template Browser面板下"d00dads - C#", 双击 “d00dads - Invoke a Stored Procedure", 让工作区显示其内容,

    然后点击工具栏上的 "Execute" 按钮,如图红框所示:

    弹出对话框,如图:

    选择数据库,存储过程,存储过程类型,点确定(OK)。

      

    然后可以看到工作区 Output 里输出了代码了。例如:

     1   using System.Data;
     2         using System.Collections.Specialized;   
     3         using System.Data.SqlClient;        
     4         
     5                 
     6         
     7         public virtual void dm_exec_cursors (int spid)
     8         {
     9             ListDictionary parameters = new ListDictionary();
    10             
    11             parameters.Add( new SqlParameter("@spid", SqlDbType.Int, 0), spid);
    12             LoadFromSqlNoExec("dm_exec_cursors", parameters);
    13         }

    这就是MyGeneration自动获取了存储过程的输入参数,然后在代码里构造相应的参数,然后生成的代码。

    这只是MyGeneration自带的模板生成的,大家可以试一试其他的模板的效果。

    里面有自动根据表结构生成BLL的类......看下效果:

      1 /*
      2 '===============================================================================
      3 '  Generated From - CSharp_dOOdads_BusinessEntity.vbgen
      4 ' 
      5 '  ** IMPORTANT  ** 
      6 '  How to Generate your stored procedures:
      7 ' 
      8 '  SQL        = SQL_StoredProcs.vbgen
      9 '  ACCESS     = Access_StoredProcs.vbgen
     10 '  ORACLE     = Oracle_StoredProcs.vbgen
     11 '  FIREBIRD   = FirebirdStoredProcs.vbgen
     12 '  POSTGRESQL = PostgreSQL_StoredProcs.vbgen
     13 '
     14 '  The supporting base class OleDbEntity is in the Architecture directory in "dOOdads".
     15 '  
     16 '  This object is 'abstract' which means you need to inherit from it to be able
     17 '  to instantiate it.  This is very easilly done. You can override properties and
     18 '  methods in your derived class, this allows you to regenerate this class at any
     19 '  time and not worry about overwriting custom code. 
     20 '
     21 '  NEVER EDIT THIS FILE.
     22 '
     23 '  public class YourObject :  _YourObject
     24 '  {
     25 '
     26 '  }
     27 '
     28 '===============================================================================
     29 */
     30 // Generated by MyGeneration Version # (1.3.0.3)
     31 using System;
     32 using System.Data;
     33 using System.Data.OleDb;
     34 using System.Collections;
     35 using System.Collections.Specialized;
     36 using MyGeneration.dOOdads;
     37 namespace Your.Namespace
     38 {
     39     public abstract class _Users : OleDbEntity
     40     {
     41         public _Users()
     42         {
     43             this.QuerySource = "Users";
     44             this.MappingName = "Users";
     45         }   
     46         //=================================================================
     47         //  public Overrides void AddNew()
     48         //=================================================================
     49         //
     50         //=================================================================
     51         public override void AddNew()
     52         {
     53             base.AddNew();
     54             
     55         }
     56         
     57         
     58         public override string GetAutoKeyColumn()
     59         {
     60             return "ID";
     61         }
     62         public override void FlushData()
     63         {
     64             this._whereClause = null;
     65             this._aggregateClause = null;
     66             base.FlushData();
     67         }
     68         
     69         //=================================================================
     70         //      public Function LoadAll() As Boolean
     71         //=================================================================
     72         //  Loads all of the records in the database, and sets the currentRow to the first row
     73         //=================================================================
     74         public bool LoadAll() 
     75         {
     76             ListDictionary parameters = null;
     77             
     78             return base.LoadFromSql("[" + this.SchemaStoredProcedure + "proc_UsersLoadAll]", parameters);
     79         }
     80     
     81         //=================================================================
     82         // public Overridable Function LoadByPrimaryKey()  As Boolean
     83         //=================================================================
     84         //  Loads a single row of via the primary key
     85         //=================================================================
     86         public virtual bool LoadByPrimaryKey()
     87         {
     88             ListDictionary parameters = new ListDictionary();
     89                     
     90             return base.LoadFromSql("[" + this.SchemaStoredProcedure + "proc_UsersLoadByPrimaryKey]", parameters);
     91         }
     92         
     93         #region Parameters
     94         protected class Parameters
     95         {
     96             
     97             public static OleDbParameter ID
     98             {
     99                 get
    100                 {
    101                     return new OleDbParameter("@ID", OleDbType.Integer, 0);
    102                 }
    103             }
    104             
    105             public static OleDbParameter Alias
    106             {
    107                 get
    108                 {
    109                     return new OleDbParameter("@Alias", OleDbType.VarChar, 2147483647);
    110                 }
    111             }
    112             
    113         }
    114         #endregion      
    115     
    116         #region ColumnNames
    117         public class ColumnNames
    118         {  
    119             public const string ID = "ID";
    120             public const string Alias = "Alias";
    121             static public string ToPropertyName(string columnName)
    122             {
    123                 if(ht == null)
    124                 {
    125                     ht = new Hashtable();
    126                     
    127                     ht[ID] = _Users.PropertyNames.ID;
    128                     ht[Alias] = _Users.PropertyNames.Alias;
    129                 }
    130                 return (string)ht[columnName];
    131             }
    132             static private Hashtable ht = null;          
    133         }
    134         #endregion
    135         
    136         #region PropertyNames
    137         public class PropertyNames
    138         {  
    139             public const string ID = "ID";
    140             public const string Alias = "Alias";
    141             static public string ToColumnName(string propertyName)
    142             {
    143                 if(ht == null)
    144                 {
    145                     ht = new Hashtable();
    146                     
    147                     ht[ID] = _Users.ColumnNames.ID;
    148                     ht[Alias] = _Users.ColumnNames.Alias;
    149                 }
    150                 return (string)ht[propertyName];
    151             }
    152             static private Hashtable ht = null;          
    153         }            
    154         #endregion  
    155         #region StringPropertyNames
    156         public class StringPropertyNames
    157         {  
    158             public const string ID = "s_ID";
    159             public const string Alias = "s_Alias";
    160         }
    161         #endregion      
    162         
    163         #region Properties
    164     
    165         public virtual Integer ID
    166         {
    167             get
    168             {
    169                 return base.GetInteger(ColumnNames.ID);
    170             }
    171             set
    172             {
    173                 base.SetInteger(ColumnNames.ID, value);
    174             }
    175         }
    176         public virtual String Alias
    177         {
    178             get
    179             {
    180                 return base.GetString(ColumnNames.Alias);
    181             }
    182             set
    183             {
    184                 base.SetString(ColumnNames.Alias, value);
    185             }
    186         }
    187         #endregion
    188         
    189         #region String Properties
    190     
    191         public virtual string s_ID
    192         {
    193             get
    194             {
    195                 return this.IsColumnNull(ColumnNames.ID) ? string.Empty : base.GetIntegerAsString(ColumnNames.ID);
    196             }
    197             set
    198             {
    199                 if(string.Empty == value)
    200                     this.SetColumnNull(ColumnNames.ID);
    201                 else
    202                     this.ID = base.SetIntegerAsString(ColumnNames.ID, value);
    203             }
    204         }
    205         public virtual string s_Alias
    206         {
    207             get
    208             {
    209                 return this.IsColumnNull(ColumnNames.Alias) ? string.Empty : base.GetStringAsString(ColumnNames.Alias);
    210             }
    211             set
    212             {
    213                 if(string.Empty == value)
    214                     this.SetColumnNull(ColumnNames.Alias);
    215                 else
    216                     this.Alias = base.SetStringAsString(ColumnNames.Alias, value);
    217             }
    218         }
    219         #endregion      
    220     
    221         
    222         private AggregateClause _aggregateClause = null;    
    223         #endregion
    224     
    225         protected override IDbCommand GetInsertCommand() 
    226         {
    227         
    228             OleDbCommand cmd = new OleDbCommand();
    229             cmd.CommandType = CommandType.StoredProcedure;
    230             cmd.CommandText = "[" + this.SchemaStoredProcedure + "proc_UsersInsert]";
    231     
    232             CreateParameters(cmd);
    233                 
    234             return cmd;
    235         }
    236     
    237         protected override IDbCommand GetUpdateCommand()
    238         {
    239         
    240             OleDbCommand cmd = new OleDbCommand();
    241             cmd.CommandType = CommandType.StoredProcedure;
    242             cmd.CommandText = "[" + this.SchemaStoredProcedure + "proc_UsersUpdate]";
    243     
    244             CreateParameters(cmd);
    245                   
    246             return cmd;
    247         }
    248     
    249         protected override IDbCommand GetDeleteCommand()
    250         {
    251         
    252             OleDbCommand cmd = new OleDbCommand();
    253             cmd.CommandType = CommandType.StoredProcedure;
    254             cmd.CommandText = "[" + this.SchemaStoredProcedure + "proc_UsersDelete]";
    255     
    256             OleDbParameter p;
    257   
    258             return cmd;
    259         }
    260         
    261         private IDbCommand CreateParameters(OleDbCommand cmd)
    262         {
    263             OleDbParameter p;
    264         
    265             p = cmd.Parameters.Add(Parameters.ID);
    266             p.SourceColumn = ColumnNames.ID;
    267             p.SourceVersion = DataRowVersion.Current;
    268             p = cmd.Parameters.Add(Parameters.Alias);
    269             p.SourceColumn = ColumnNames.Alias;
    270             p.SourceVersion = DataRowVersion.Current;
    271             return cmd;
    272         }
    273     }
    274 }

    这就是自动获得表结构,然后从字段映射成类里面的成员,并且还有一些插入,更新,删除的代码。

    当然自带的模板生成的代码不一定符合我们的需要,但是我们可以根据需要自己写一些模板来生成符合自己需要的代码,这也是非常容易的事,欲知如何实现,请看下回文章。

    本文转载自:http://blog.csdn.net/zxcred/article/details/2778193

  • 相关阅读:
    java生成验证码
    springmvc笔记(来自慕课网)
    angularJs编写多指令的情况
    四年前端开发的迷茫.
    angularJs的ui-router总结
    grunt构建前端自动化的开发环境
    socket传送文件
    socket--粘包
    socket--接受大数据
    动态导入模块
  • 原文地址:https://www.cnblogs.com/qiernonstop/p/3630090.html
Copyright © 2011-2022 走看看