zoukankan      html  css  js  c++  java
  • 如何使用CodeSmith(转载)

    CodeSmith 是一种语法类似于asp.net的基于模板的代码生成器,程序可以自定义模板,从而减少重复编码的劳动量,提高效率。
         安装CodeSmith 2.6注册后发现有两个可运行程序CodeSmith Studio.exe和CodeSmith Explorer.exe
         CodeSmith Studio.exe用来创建自定义模板
         CodeSmith Explorer.exe用来导入模板并且生成代码
        打开 CodeSmith Studio.exe,新建一个C#模板。发现有如下类似与asp.net的标识符号
         <%  %>
         <%= %>
         <%@  %>
        <script runat="template"> </script>
       下面通过简单的例子说明如何用  CodeSmith 创建模板并生成代码
        新建一个空的txt文件,在文件上部输入如下一个CodeTemplate指示,Language 和TargetLanguage分别代表模板语言和创建代码语言,

    然后声明几个变量,用来为了能够在以后生成的代码嵌入,这里声明了三个名为NameSpace,ClassName,Contxt的变量。其他参数一目了然就不再说明了,

    <%@ Property Name="NameSpace" Type="String"
          Category="Context"
          Description="The namespace to use for this class" %>
    <%@ Property Name="ClassName" Type="String"
          Category="Context"
          Description="The name of the class to generate" %>
    <%@ Property Name="DevelopersName" Type="String"
          Category="Context"
          Description="The name to include in the comment header" %>
    接下来建立将要生成代码的框架,在适当位置引用刚刚声明的变量名
    using System;
    namespace <%=NameSpace %>
    {
          /// <summary>
          /// Summary description for <%=ClassName %>.
          /// </summary>
          public class <%=ClassName %>
          {
                public <%=ClassName %>()
               {
                }
          }
    }
    最后,打开CodeSmith Explorer.exe,加载此模板,并且在属性对话框中任意更改声明的变量名,按Generate按钮生成合适的代码
    image004

    以上简单的说明了CodeSmith的功能
      下面看看在数据库访问中它是如何最小化我们的工作的
      在这里我们要用到CodeSmith API中一个叫SchemaExplorer的组件,它提供了一系列类来操作数据库的框架,我们可以用它来创建表和存储过程,得到字段类型,字段名等。
    如下是更新NorthWind数据库中orders表记录的存储过程,我们来看看如何自动生成它

    CREATE PROCEDURE dbo.UpdateOrders
          @OrderID int,
          @CustomerID nchar(5),
          @EmployeeID int,
          @OrderDate datetime,
          @RequiredDate datetime,
          @ShippedDate datetime,
          @ShipVia int,
          @Freight money,
          @ShipName nvarchar(40),
          @ShipAddress nvarchar(60),
          @ShipCity nvarchar(15),
          @ShipRegion nvarchar(15),
          @ShipPostalCode nvarchar(10),
          @ShipCountry nvarchar(15)
    AS
     
    UPDATE [Orders] SET
          [CustomerID] = @CustomerID,
          [EmployeeID] = @EmployeeID,
          [OrderDate] = @OrderDate,
          [RequiredDate] = @RequiredDate,
          [ShippedDate] = @ShippedDate,
          [ShipVia] = @ShipVia,
          [Freight] = @Freight,
          [ShipName] = @ShipName,
          [ShipAddress] = @ShipAddress,
          [ShipCity] = @ShipCity,
          [ShipRegion] = @ShipRegion,
          [ShipPostalCode] = @ShipPostalCode,
          [ShipCountry] = @ShipCountry
    WHERE
          
          [OrderID] = @OrderID

    第一步还是创建一个CodeTemplate指示,注意 TargetLanguage属性改为了T-SQL,因为创建的SQL语言代码
    <%@ CodeTemplate Language="C#" TargetLanguage="T-SQL" Description="Generates a update stored procedure." %>
     
    然后加载SchemaExplorer组件,并导入 SchemaExplorer命名空间,看这里是不是和asp.net很像
    <%@ Assembly Name="SchemaExplorer" %> 
    <%@ Import Namespace="SchemaExplorer" %>

    接下来声明变量,因为要从数据库表中读取框架所以 Type 属性为SchemaExplorer.TableSchema
    <%@ Property   Name="SourceTable"   Type="SchemaExplorer.TableSchema"    Category="Context"   Description="Table that the stored procedures should be based on." %>

    下面就要写实际将要输出代码部分的模板了。
    先写存储过程的第一行 ,<%%>内为引用前面声明变量名,代表表名

    CREATE PROCEDURE dbo.Update<%=SourceTable.Name %>

    第二步为存储过程创造将要声明的参数列表

    //开始循环遍历每列

    //开始循环遍历每列 
        <% for (int i = 0; i < SourceTable.Columns.Count; i++) { %>
        //传递每列给GetSqlParameterStatement函数 
        <%= GetSqlParameterStatement(SourceTable.Columns[i]) %>
        //循环结束条件
        <% if (i < SourceTable.Columns.Count - 1) { %>,<% } %>
        <% } % > 
         AS

    定义GetSqlParameterStatement方法接受列参数返回参数名,和字段类型,注意函数要放在
    <script runat="template"></script> 里

    <script runat="template">
    
    public string GetSqlParameterStatement(ColumnSchema column)
    
    {
          string param = "@" + column.Name + " " + column.NativeType;
          switch (column.DataType)
          {
                case DbType.Decimal:
               {    
                 param += "(" + column.Precision + ", " + column.Scale + ")";
                 break;
               }
                default:
             {
                   if (column.Size > 0)
                {
                          param += "(" + column.Size + ")";
                   }
                 break;
               }
           }
         return param;
    }
    </script>


    接下来创建存储过程的Update 部分,语法类似不再说明

    UPDATE [<%= SourceTable.Name %>] SET
          <% for (int i = 0; i < SourceTable.NonPrimaryKeyColumns.Count; i++) { %>
          [<%= SourceTable.NonPrimaryKeyColumns[i].Name %>] = @<%= SourceTable.NonPrimaryKeyColumns[i].Name %><% if (i < SourceTable.NonPrimaryKeyColumns.Count - 1) { %>,<% } %>
          <% } %> 
    //where条件,注意主键提取方法
    WHERE
          <% for (int i = 0; i < SourceTable.PrimaryKey.MemberColumns.Count; i++) { %>
          <% if (i > 0) { %>AND <% } %>
          [<%= SourceTable.PrimaryKey.MemberColumns[i].Name %>] = @<%= SourceTable.PrimaryKey.MemberColumns[i].Name %>
          <% } %>

    最终为模板为如下形式

    <%@ CodeTemplate Language="C#" TargetLanguage="T-SQL"
          Description="Generates a update stored procedure." %>
     
    <%@ Property Name="SourceTable" Type="SchemaExplorer.TableSchema"
          Category="Context"
          Description="Table that the stored procedures should be based on." %>
     
    <%@ Assembly Name="SchemaExplorer" %>
     
    <%@ Import Namespace="SchemaExplorer" %>
          
    <script runat="template">
    public string GetSqlParameterStatement(ColumnSchema column)
    {
          string param = "@" + column.Name + " " + column.NativeType;
     
          switch (column.DataType)
          {
                case DbType.Decimal:
                {
                      param += "(" + column.Precision + ", " + column.Scale + ")";
                      break;
                }
                default:
                {
                      if (column.Size > 0)
                      {
                            param += "(" + column.Size + ")";
                      }
                      break;
                }
          }
     
          return param;
    }
    </script>
     
    CREATE PROCEDURE dbo.Update<%= SourceTable.Name %>
          <% for (int i = 0; i < SourceTable.Columns.Count; i++) { %>
          <%= GetSqlParameterStatement(SourceTable.Columns[i]) %><% if (i < SourceTable.Columns.Count - 1) { %>,<% } %>
          <% } %>
    AS
     
    UPDATE [<%= SourceTable.Name %>] SET
          <% for (int i = 0; i < SourceTable.NonPrimaryKeyColumns.Count; i++) { %>
          [<%= SourceTable.NonPrimaryKeyColumns[i].Name %>] = @<%= SourceTable.NonPrimaryKeyColumns[i].Name %><% if (i < SourceTable.NonPrimaryKeyColumns.Count - 1) { %>,<% } %>
          <% } %>
    WHERE
          <% for (int i = 0; i < SourceTable.PrimaryKey.MemberColumns.Count; i++) { %>
          <% if (i > 0) { %>AND <% } %>
          [<%= SourceTable.PrimaryKey.MemberColumns[i].Name %>] = @<%= SourceTable.PrimaryKey.MemberColumns[i].Name %>
          <% } %>

    将其用CodeSmith Explorer.exe打开

    image005

    可以任意选择数据库中的表,这里选择NorthWind中的0rders表image006

    然后生成代码,就创建好了存储过程

    CREATE PROCEDURE dbo.UpdateOrders
          @OrderID int,
          @CustomerID nchar(5),
          @EmployeeID int,
          @OrderDate datetime,
          @RequiredDate datetime,
          @ShippedDate datetime,
          @ShipVia int,
          @Freight money,
          @ShipName nvarchar(40),
          @ShipAddress nvarchar(60),
          @ShipCity nvarchar(15),
          @ShipRegion nvarchar(15),
          @ShipPostalCode nvarchar(10),
          @ShipCountry nvarchar(15)
    AS
     
    UPDATE [Orders] SET
          [CustomerID] = @CustomerID,
          [EmployeeID] = @EmployeeID,
          [OrderDate] = @OrderDate,
          [RequiredDate] = @RequiredDate,
          [ShippedDate] = @ShippedDate,
          [ShipVia] = @ShipVia,
          [Freight] = @Freight,
          [ShipName] = @ShipName,
          [ShipAddress] = @ShipAddress,
          [ShipCity] = @ShipCity,
          [ShipRegion] = @ShipRegion,
          [ShipPostalCode] = @ShipPostalCode,
          [ShipCountry] = @ShipCountry
    WHERE
          
          [OrderID] = @OrderID

    同样,我们可以选择其他的表创建 Updata存储过程,也可以自定义其他诸如insert delete等的存储过程,是不是很方便?^-^


    以上只是CodeSmith的简单应用,还有其他的功能有待大家探索了。
    关于CodeSmith社区一些模板资源,大家可以去如下地址选择下载
    CodeSmith Peer Support Forum
    Codesmith templates library

  • 相关阅读:
    Java内存泄漏的排查总结
    多文本匹配 AC算法(Aho-Corasick)
    Linux下进程管理利器—supervise(监控并将死掉的程序重启)
    maven pom项目的dependencies转gradle格式
    Protocol Buffers官方文档(开发指南)
    Spring的工具类StringUtils使用
    springboot2 中Druid和ibatis(baomidou) 遇到org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.iflytek.pandaai.service.multi.mapper.TanancyMapper
    gradle 多模块Springboot项目 compile project引用其他模块的坑
    JAVA 运行springboot jar包设置classpath
    mysql8
  • 原文地址:https://www.cnblogs.com/gaotianle/p/1733165.html
Copyright © 2011-2022 走看看