zoukankan      html  css  js  c++  java
  • 分享改进 完全定制自己的代码生成器

    codesmith确实是款不错的工具 但是它并不开源 对于一些有自己特殊需求的用户只能自己另想其他解决方案 例如我说想做一个web版本的代码生成器或者说用户没有c#基础

    这里开源一个之前做过的工具 当初的目的主要是解决在框架当中局部更新的问题
    因为在大部分orm框架当中都是简单的获取一个实体 然后这个实体某个值 然后更新的时候 还是传入这个改变的实体 不过严格意义上来说 在你传入更新实体的时候 它的其他字段说不定已经被其他请求更新过了 所以导致你的这次更新会覆盖掉别人的更新 当然也会有同一字段的问题 不过这里不深入讨论该问题 重点在代码生成上

    另外一个意义 就是让大家了解一下一般的代码生成器的工作流程以及实现方法


    Github地址 https://github.com/dubing/CodePorter

    使用方法很简单 先输入数据库连接字符串 下面会出现table和view,当然自己可以根据源代码加载更多的内容

    我程序里主要生成实体层和数据处理层所以我提供了2个文本框 一个是实体层的命名空间 一个是数据处理层的命名的命名空间,这样就不用在模板里设置,可以在win界面或者web界面直接修改

    选择好表和view并且设置好命名空间后点击启动 左下角提示成功后就可以打开目录 查看自己生成的文件

    生成的实体文件

    这里的PartiallyColumnAttribute主要就是用来解决局部更新问题,和代码生成本身无关联。

    DA文件

        //------------------------------------
        //用途:表LitespeedActivity的数据处理类(工具自动生成)
        //作者:杜兵
        //时间:2015-03-11 05:43:32
        //-------------------------------------
    
        using System;
        using System.Data;
        using System.Data.Common;
        using Model.Service;
        using Ctrip.TMPay.Framework.Common;
        using Ctrip.TMPay.DataAccess.Common;
    
        namespace DataAccess.Service
        {
            public partial class LitespeedActivityDA : BaseDA<LitespeedActivityDA>
            {
                
                /// <summary>
                /// 根据主键获取LitespeedActivity
                ///</summary>
                ///< param name="serverName"></param>
                ///< returns></returns>
                public LitespeedActivityEntity GetLitespeedActivity(String serverName)
                {
                    DbCommand dbCmd = DbObject.GetSqlStringCommand(SqlCommandConstants.LitespeedActivitySelectCommand);
                    DbObject.AddInParameter(dbCmd, "@ServerName", DbType.String, serverName);
                    LitespeedActivityEntity litespeedActivityEntity = null;
                    using (IDataReader dataReader = DbObject.ExecuteReader(dbCmd))
                    {
                        if (dataReader.Read())
                        {
                              litespeedActivityEntity = new LitespeedActivityEntity{
                                  ServerName = DbFieldHelper.GetString(dataReader, "ServerName"),
                                  ActivityID = DbFieldHelper.GetInt32(dataReader, "ActivityID"),
                                  DatabaseID = DbFieldHelper.GetInt32(dataReader, "DatabaseID"),
                                  ActivityTypeID = DbFieldHelper.GetInt32(dataReader, "ActivityTypeID"),
                                  StartTime = DbFieldHelper.GetDateTime(dataReader, "StartTime"),
                                  FinishTime = DbFieldHelper.GetDateTime(dataReader, "FinishTime"),
                                  StatusTypeID = DbFieldHelper.GetInt32(dataReader, "StatusTypeID"),
                                  DatabaseSize = DbFieldHelper.GetDouble(dataReader, "DatabaseSize"),
                                  PercentCompleted = DbFieldHelper.GetInt32(dataReader, "PercentCompleted"),
                                  ActivityDetail = DbFieldHelper.GetString(dataReader, "ActivityDetail"),
                                  ErrorMessage = DbFieldHelper.GetString(dataReader, "ErrorMessage"),
                                  ResultMessage = DbFieldHelper.GetString(dataReader, "ResultMessage"),
                                  ReplicateID = DbFieldHelper.GetGuid(dataReader, "ReplicateID"),
                                  LS = DbFieldHelper.GetByte(dataReader, "LS"),
                                  PID = DbFieldHelper.GetInt32(dataReader, "PID"),
                                  NativeSize = DbFieldHelper.GetDouble(dataReader, "NativeSize"),
                                  BackupSize = DbFieldHelper.GetDouble(dataReader, "BackupSize"),
                                  BackupTime = DbFieldHelper.GetDouble(dataReader, "BackupTime"),
                                  AttachedNativeSize = DbFieldHelper.GetDouble(dataReader, "AttachedNativeSize"),
                                  AttachedBackupSize = DbFieldHelper.GetDouble(dataReader, "AttachedBackupSize"),
                                  AttachedBackupTime = DbFieldHelper.GetDouble(dataReader, "AttachedBackupTime"),
                                  
                              };
                         }
                     }
                     return litespeedActivityEntity;
                 }   
        
                /// <summary>
                /// 根据主键获取LitespeedActivity
                ///</summary>
                ///< param name="activityID"></param>
                ///< returns></returns>
                public LitespeedActivityEntity GetLitespeedActivity(Int32 activityID)
                {
                    DbCommand dbCmd = DbObject.GetSqlStringCommand(SqlCommandConstants.LitespeedActivitySelectCommand);
                    DbObject.AddInParameter(dbCmd, "@ActivityID", DbType.Int32, activityID);
                    LitespeedActivityEntity litespeedActivityEntity = null;
                    using (IDataReader dataReader = DbObject.ExecuteReader(dbCmd))
                    {
                        if (dataReader.Read())
                        {
                              litespeedActivityEntity = new LitespeedActivityEntity{
                                  ServerName = DbFieldHelper.GetString(dataReader, "ServerName"),
                                  ActivityID = DbFieldHelper.GetInt32(dataReader, "ActivityID"),
                                  DatabaseID = DbFieldHelper.GetInt32(dataReader, "DatabaseID"),
                                  ActivityTypeID = DbFieldHelper.GetInt32(dataReader, "ActivityTypeID"),
                                  StartTime = DbFieldHelper.GetDateTime(dataReader, "StartTime"),
                                  FinishTime = DbFieldHelper.GetDateTime(dataReader, "FinishTime"),
                                  StatusTypeID = DbFieldHelper.GetInt32(dataReader, "StatusTypeID"),
                                  DatabaseSize = DbFieldHelper.GetDouble(dataReader, "DatabaseSize"),
                                  PercentCompleted = DbFieldHelper.GetInt32(dataReader, "PercentCompleted"),
                                  ActivityDetail = DbFieldHelper.GetString(dataReader, "ActivityDetail"),
                                  ErrorMessage = DbFieldHelper.GetString(dataReader, "ErrorMessage"),
                                  ResultMessage = DbFieldHelper.GetString(dataReader, "ResultMessage"),
                                  ReplicateID = DbFieldHelper.GetGuid(dataReader, "ReplicateID"),
                                  LS = DbFieldHelper.GetByte(dataReader, "LS"),
                                  PID = DbFieldHelper.GetInt32(dataReader, "PID"),
                                  NativeSize = DbFieldHelper.GetDouble(dataReader, "NativeSize"),
                                  BackupSize = DbFieldHelper.GetDouble(dataReader, "BackupSize"),
                                  BackupTime = DbFieldHelper.GetDouble(dataReader, "BackupTime"),
                                  AttachedNativeSize = DbFieldHelper.GetDouble(dataReader, "AttachedNativeSize"),
                                  AttachedBackupSize = DbFieldHelper.GetDouble(dataReader, "AttachedBackupSize"),
                                  AttachedBackupTime = DbFieldHelper.GetDouble(dataReader, "AttachedBackupTime"),
                                  
                              };
                         }
                     }
                     return litespeedActivityEntity;
                 }   
        
                /// <summary>
                /// 全参数更新LitespeedActivity
                ///</summary>
                ///< param name="litespeedActivityEntity">LitespeedActivityEntity</param>
                ///< returns></returns>
                public BizResult<string> UpdateLitespeedActivity(LitespeedActivityEntity litespeedActivityEntity)
                {
                    FillParams(litespeedActivityEntity);
                    return PartiallyUpdateLitespeedActivity(litespeedActivityEntity);
                }    
        
                /// <summary>
                /// 部分参数更新LitespeedActivity
                ///</summary>
                ///< param name="litespeedActivityEntity">LitespeedActivityEntity</param>
                ///< returns></returns>
                public BizResult<string> PartiallyUpdateLitespeedActivity(LitespeedActivityEntity litespeedActivityEntity)
                {              
                     return ExecuteSP(SqlProcedureConstants.LitespeedActivityUpdateSpName, CheckUpdate, litespeedActivityEntity);
                }   
                
                /// <summary>
                /// 创建LitespeedActivity
                ///</summary>
                ///< param name="litespeedActivityEntity">LitespeedActivityEntity</param>
                ///< returns></returns>
                public BizResult<string> CreateLitespeedActivity(LitespeedActivityEntity litespeedActivityEntity)
                {
                     FillParams(litespeedActivityEntity);
                     return ExecuteSP(SqlProcedureConstants.LitespeedActivityInsertSpName, null, litespeedActivityEntity);
                }  
                
                /// <summary>
                /// 删除LitespeedActivity
                ///</summary>
                ///< param name="litespeedActivityEntity">LitespeedActivityEntity</param>
                ///< returns></returns>
                public BizResult<string> DeleteLitespeedActivity(LitespeedActivityEntity litespeedActivityEntity)
                {
                     FillPKParams(litespeedActivityEntity);
                     return ExecuteSP(SqlProcedureConstants.LitespeedActivityDeleteSpName, null, litespeedActivityEntity);
                }  
           }
        }
      
    

    还有其他的一些文件就不一一列出了

    原理很简单 也是根据模板。不过和codesmith不同的是 我这里用的是xsl模板包括语法

    基于xml的语法并不难 就算不懂.net的人学习半个小时也可以自己定制模板了

    举个例子

    <?xml version="1.0" encoding="utf-8" standalone="yes"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:output encoding="utf-8" method="text" indent="no"/>
      <xsl:variable name="BaseName" select="/DocumentElement/@BaseName"/>
      <xsl:variable name="BaseDbObject" select="/DocumentElement/@BaseDbObject"/>
      <xsl:variable name="DefaultNamespace" select="/DocumentElement/@DefaultNamespace"/>
      <xsl:variable name="DateTime" select="/DocumentElement/@DateTime"/>
      <xsl:variable name="SchemaTable" select="/DocumentElement/SchemaTable[translate(IsHidden,'TRUE','true')!='true']"/>
      <xsl:variable name="TableClassName">
        <xsl:value-of select="$BaseName"/>Table
      </xsl:variable>
      <xsl:template match="/">    //------------------------------------
        //用途:表<xsl:value-of select="$BaseDbObject"/>的实体类(工具自动生成)
        //作者:杜兵 
        //时间:<xsl:value-of select="$DateTime"/>
        //-------------------------------------
    
        using System;
        using System.Data;
    
        namespace <xsl:value-of select="$DefaultNamespace"/>
        {
            [Serializable]
            public partial class <xsl:value-of select="$BaseName"/>Entity : BaseEntity
            {<xsl:for-each select="$SchemaTable">  
              <xsl:variable name="PublicPropertyName">
                <xsl:value-of select="PropertyName"/>
              </xsl:variable>    
              <xsl:variable name="ShortDataType">
                <xsl:choose>
                  <xsl:when test="ProviderDataType='System.Data.SqlTypes.SqlXml'">System.Xml.Linq.XElement</xsl:when>
                  <xsl:otherwise>
                    <xsl:value-of select="ShortDataType"/>
                  </xsl:otherwise>
                </xsl:choose>
              </xsl:variable>
              <xsl:variable name="DbDataType">
                <xsl:choose>
                  <xsl:when test="ProviderTypeName='SqlDbType.Timestamp'">rowversion</xsl:when>
                  <xsl:when test="ProviderTypeName='SqlDbType.Variant'">Variant</xsl:when>
                  <xsl:otherwise>
                    <xsl:value-of select="DataTypeFullName"/>
                  </xsl:otherwise>
                </xsl:choose>
              </xsl:variable>
              <xsl:variable name="Description">
                <xsl:value-of select="Description"/>
              </xsl:variable><xsl:variable name="DbType">
              <xsl:value-of select="DBDataTypeFullName"/>
            </xsl:variable>
              /// <summary>
              /// <xsl:value-of select="$Description"/>
              ///</summary>       
              [PartiallyColumnAttribute(DbType = <xsl:value-of select="$DbType"/> <xsl:choose><xsl:when test="AllowDBNull='false'">, CanBeNull = false</xsl:when><xsl:otherwise>, CanBeNull = true</xsl:otherwise></xsl:choose><xsl:if test="IsKey='true'">, IsPrimaryKey = true</xsl:if>)]
              public <xsl:value-of select="$ShortDataType"/><xsl:text> </xsl:text><xsl:value-of select="$PublicPropertyName"/> {  get; set; }</xsl:for-each> 
            }
        }
      </xsl:template>
    </xsl:stylesheet>

      这里代码里模板实现主要是解决局部更新的功能,大家可以根据自己不同的需求来修改部分逻辑。

      核心的配置文件在config下CodeSet.xml

      主要的配置节点如下

      <generatorSettings>
        <ConstantsGenerator>
          <add key="DataSourceType" value="CodePorter.Core.DbTableSource"/>
          <add key="XslTemplate" value="CodePorter.Templates.SqlConstantsTemplate.xsl"/>
          <add key="TargetFile" value=".RepositorySqlConstants.cs"/>
          <add key="BeginRegion" value="#region select command,#region sp name"/>
          <add key="EndRegion" value="#endregion,#endregion"/>
        </ConstantsGenerator>
        <BaseDbEntityGenerator>
          <add key="DataSourceType" value="CodePorter.Core.DbTableSource"/>
          <add key="XslTemplate" value="CodePorter.Templates.BaseDbEntityTemplate.xsl"/>
          <add key="TargetFile" value=".EntityBaseEntity.cs"/>
        </BaseDbEntityGenerator>
        <DbEntityGenerator>
          <add key="DataSourceType" value="CodePorter.Core.DbTableSource"/>
          <add key="XslTemplate" value="CodePorter.Templates.DbEntityTemplate.xsl"/>
          <add key="TargetFile" value=".Entity\%BASENAME%Entity.cs"/>
        </DbEntityGenerator>
        <BaseDAGenerator>
          <add key="DataSourceType" value="CodePorter.Core.DbTableSource"/>
          <add key="XslTemplate" value="CodePorter.Templates.BaseDATemplate.xsl"/>
          <add key="TargetFile" value=".RepositoryBaseDA.cs"/>
        </BaseDAGenerator>
        <DAGenerator>
          <add key="DataSourceType" value="CodePorter.Core.DbTableSource"/>
          <add key="XslTemplate" value="CodePorter.Templates.DATemplate.xsl"/>
          <add key="TargetFile" value=".Repository\%BASENAME%DA.cs"/>
        </DAGenerator>
      </generatorSettings>

      细节比较多,但是通过源代码大家应该理解都没有问题,如果有不清楚的地方可以给我留言。后续会放出更多以前做过的工具。


     希望对大家有帮助。

  • 相关阅读:
    JAVA日报
    JAVA日报
    JAVA日报
    JAVA日报
    leetcode刷题笔记 260题 只出现一次的数字 III
    leetcode刷题笔记 241题 为运算表达式设计优先级
    leetcode刷题笔记 258题 各位相加
    leetcode刷题笔记 257题 二叉树的所有路径
    leetcode刷题笔记 242题 有效的字母异位词
    leetcode刷题笔记 240题 搜索二维矩阵 II
  • 原文地址:https://www.cnblogs.com/dubing/p/4331601.html
Copyright © 2011-2022 走看看