鍍金池/ 教程/ C++/ 自動(dòng)生成Yii Framework ActiveRecord類簡(jiǎn)單模板
使用主從代碼模板
CodeTemplateInfo 對(duì)象
引用其它文件或 .Net 類庫(kù)
編寫第一個(gè)代碼模板
Progress 對(duì)象
基本語(yǔ)法-使用注釋
基本語(yǔ)法-轉(zhuǎn)義Asp.Net標(biāo)記
調(diào)試
為 Yii Framework 創(chuàng)建生成 ActiveRecord 的代碼模板
基本語(yǔ)法-聲明和使用屬性
自動(dòng)生成Yii Framework ActiveRecord類簡(jiǎn)單模板
Merge 策略
使用 XMLProperty
CodeTemplate 對(duì)象
基本語(yǔ)法-CodeTemplate 指令
概述
使用 SchemaExplorer 來(lái)獲取數(shù)據(jù)庫(kù)定義

自動(dòng)生成Yii Framework ActiveRecord類簡(jiǎn)單模板

上例介紹了使用 CodeSmith 編寫代碼模板的基本方法,本例實(shí)現(xiàn)一個(gè)較為實(shí)用的代碼模板,通過(guò)數(shù)據(jù)庫(kù)自動(dòng)為 Yii Framework 生成所需要的 ActiveRecord 類。

本例通過(guò)修改 Yii Framework 開(kāi)發(fā)教程(26) 數(shù)據(jù)庫(kù)-Active Record 示例,原例是手工編寫 Employee.php ActiveRecord。

首先為工程添加一個(gè) C# 項(xiàng)目(任意類型,我們只是利用這個(gè)項(xiàng)目來(lái)包含 CodeSmith 項(xiàng)目),然后添加一個(gè) CodeSmith 項(xiàng)目和一個(gè) CodeSmith 模板。然后參考 CodeSmith 使用教程(1): 概述 使用Schema Explorer 添加一個(gè)數(shù)據(jù)連接,本例連接到 Chinook 數(shù)據(jù)庫(kù):

http://wiki.jikexueyuan.com/project/codesmith/images/13.png" alt="第13張" />

創(chuàng)建的代碼模板 PhpActiveRecord.cst 定義個(gè)屬性 TableName(數(shù)據(jù)庫(kù)表名),復(fù)制 Yii Framework 開(kāi)發(fā)教程(26) 數(shù)據(jù)庫(kù)-Active Record 示例中 Employee.php 的定義并使用屬性,代碼如下:

<%@ Template Language="C#" TargetLanguage="PHP" Debug="False" %>

<%@ Property Name="TableName" Type="System.String" Description="Table name" %>

<?php

class <%= TableName %> extends CActiveRecord
{
    public static function model($className=__CLASS__)
    {
        return parent::model($className);
    }

    public function tableName()
    {
        return '<%= TableName %>';
    }
}

?>

<script runat="template">
  public override string GetFileName() {
    return TableName + ".php" ;
}
</script>

這時(shí)就可以通過(guò)定義 TableName 的屬性給任意數(shù)據(jù)表生成對(duì)應(yīng)的 ActiveRecord PHP 類了。 不過(guò)這還是要手工來(lái)一個(gè)一個(gè)來(lái)配置表名。 本例通過(guò)一個(gè)主模板和一個(gè)從模板的方式通過(guò)連接數(shù)據(jù)庫(kù)自動(dòng)為所有的表生成對(duì)應(yīng)的 ActiveRecord

使用主從模板的具體用法后面再介紹,簡(jiǎn)單的說(shuō)子模板相當(dāng)于子函數(shù),主模板類似于主函數(shù)可以調(diào)用子函數(shù),主模板通過(guò)調(diào)用子模板,傳給子模板屬性從而可以生成多個(gè)文件。

創(chuàng)建一個(gè)代碼模板 YiiDataModel.cst 作為主模板,使用子模板首先需要在主模板中進(jìn)行注冊(cè)才能使用:

<%@ Register Name="ActiveRecord" Template="PhpActiveRecord.cst" MergeProperties="false"  %>

完整代碼如下:

<%@ CodeTemplate Language="C#" TargetLanguage="Text"
  Description="List all database tables" %>
<%@ Import Namespace="System.IO" %>
<%@ Property Name="SourceDatabase" Type="SchemaExplorer.DatabaseSchema"
  Category="Context" Description="Database containing the tables." %>

<%@ Register Name="ActiveRecord" Template="PhpActiveRecord.cst"
 MergeProperties="false"  %>
<%@ Assembly Name="SchemaExplorer" %>
<%@ Import Namespace="SchemaExplorer" %>

<script runat="template">
public string FirstLetterToUpper(string str)
{
    if (str != null)
    {
        if(str.Length > 1)
            return char.ToUpper(str[0]) + str.Substring(1);
        else
            return str.ToUpper();
    }
    return str;
}

</script>

<% for (int i = 0; i < SourceDatabase.Tables.Count; i++) { %>
   <%  string name= FirstLetterToUpper(SourceDatabase.Tables[i].Name); %>
   <%  string filename= @"../ActiveRecordDemo/protected/models/"+name+".php"; %>
     // instantiate the sub-template
    <%  ActiveRecord activeRecord = this.Create<ActiveRecord>();%>
    <%  activeRecord.TableName= name; %>
    <%  activeRecord.RenderToFile(filename,true); %>
<% } %>

FirstLetterToUpper 為C#函數(shù),主要是把數(shù)據(jù)庫(kù)表名的第一個(gè)字母變?yōu)榇髮懀?C# 代碼)。

SchemaExplorer 為 CodeSmith 提供的數(shù)據(jù)庫(kù)訪問(wèn)庫(kù),可以用來(lái)獲取數(shù)據(jù)庫(kù) Schema 的信息,如包含的表名,字段屬性,主鍵外鍵等(后面具體介紹)

在主模板中,通過(guò) ActiveRecord 來(lái)訪問(wèn)子模板(名字 ActiveRecord 為注冊(cè)子模板時(shí)定義) ,使用 this.create 創(chuàng)建子模板實(shí)例,然后傳入 TableName 屬性,調(diào)用 RenderToFile 將子模板的結(jié)果寫道指定的文件中。

此時(shí)在 CodeSmith.csp 中添加主模板,配置數(shù)據(jù)庫(kù)為 Chinook,然后生成代碼

Rendering output 'YiiDataModel'...

  Generated: D:\tmp\ActiveRecordDemo\ActiveRecordDemo\protected\models\Album.php
  Generated: D:\tmp\ActiveRecordDemo\ActiveRecordDemo\protected\models\Artist.php
  Generated: D:\tmp\ActiveRecordDemo\ActiveRecordDemo\protected\models\Customer.php
  Generated: D:\tmp\ActiveRecordDemo\ActiveRecordDemo\protected\models\Employee.php
  Generated: D:\tmp\ActiveRecordDemo\ActiveRecordDemo\protected\models\Genre.php
  Generated: D:\tmp\ActiveRecordDemo\ActiveRecordDemo\protected\models\Invoice.php
  Generated: D:\tmp\ActiveRecordDemo\ActiveRecordDemo\protected\models\Invoiceline.php
  Generated: D:\tmp\ActiveRecordDemo\ActiveRecordDemo\protected\models\Mediatype.php
  Generated: D:\tmp\ActiveRecordDemo\ActiveRecordDemo\protected\models\Playlist.php
  Generated: D:\tmp\ActiveRecordDemo\ActiveRecordDemo\protected\models\Playlisttrack.php
  Generated: D:\tmp\ActiveRecordDemo\ActiveRecordDemo\protected\models\Track.php
  Generated: D:\tmp\ActiveRecordDemo\CodeSmith\YiiDataModel.txt
Done rendering outputs: 1 succeeded, 0 failed, 0 skipped (1

刷新項(xiàng)目可以看到自動(dòng)生成的代碼文件

http://wiki.jikexueyuan.com/project/codesmith/images/14.png" alt="第14張" />

本例只是為每個(gè)數(shù)據(jù)表生成最簡(jiǎn)單的 ActiveRecord,如果需要生成關(guān)聯(lián) ActiveRecord,可以進(jìn)一步根據(jù)表之間的關(guān)系為每個(gè) ActiveRecord 生成所需的 relations 方法,后面有時(shí)間進(jìn)一步介紹。

本例下載