代码自动生成工具MyGeneration之一(程序员必备工具)

来源:互联网 发布:绘画软件sai下载 编辑:程序博客网 时间:2024/04/29 18:51

   




 本博客已搬家至: http://www.kai-zhou.com,  其他博客已停止更新,欢迎访问:代码自动生成工具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 面板 列出了一些模板,这是自动生成代码需要用到的模板。安装的时候会自己带很多模板。

   MyMeta Browser则列出了当前连接的数据库上有些什么库,表,存储过程。

   工作区则是具体模板对应的代码。

   

   先让我们体验一下吧。

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

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

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

   代码自动生成工具MyGeneration之二

   

   郑重申明:本文是本人花时间花精力的原创文章,如要转载请注明转自

   http://blog.csdn.net/zxcred