当前位置:K88软件开发文章中心编程工具CodeSmith → 文章内容

CodeSmith 为 Yii Framework 创建生成 ActiveRecord 的代码模板

减小字体 增大字体 作者:佚名  来源:网上搜集  发布时间:2019-1-24 10:16:41

由 珍珍阿姨 创建, 最后一次修改 2016-08-12 为 Yii Framework 创建生成 ActiveRecord 的代码模板在 CodeSmith 使用教程(3): 自动生成 Yii Framework ActiveRecord 我们通过 SchemaExploer 为 Yii Framework 从数据库生成简单的 ActiveRecord 类,没有考虑到表和表之间的关系。本例我们使用 CodeSmith 为 Yii Framework 创建一个通用的代码模板,可以使用上例介绍的SchemaExploer ,不过在查看 CodeSmith 自带的例子中有个生成 Hibernate 的例子,这个模板的使用可以参见 CodeSmith 使用教程(1): 概述 ,CodeSmith 提供了这个模板的源码,使用到了 CodeSmith.SchemaHelper (CodeSmith 没有提供相应的文档),不过可以通过阅读 NHiberante 的模板了解其一般用法。为生成 Yii Framework ActiveRecord 类之间的 relation ,先要了解一下表和表之间的关系:两个 AR 类之间的关系直接通过 AR 类所代表的数据表之间的关系相关联。 从数据库的角度来说,表 A 和 B 之间有三种关系:一对多(one-to-many,例如 tbl_user 和 tbl_post),一对一( one-to-one 例如 tbl_user 和tbl_profile)和 多对多(many-to-many 例如 tbl_category 和 tbl_post)。 在 AR 中,有四种关系:BELONGS_TO(属于): 如果表 A 和 B 之间的关系是一对多,则 表 B 属于 表 A (例如 Post 属于 User);HAS_MANY(有多个): 如果表 A 和 B 之间的关系是一对多,则 A 有多个 B (例如 User 有多个 Post);HAS_ONE(有一个): 这是 HAS_MANY 的一个特例,A 最多有一个 B (例如 User 最多有一个 Profile);MANY_MANY: 这个对应于数据库中的 多对多 关系。 由于多数 DBMS 不直接支持 多对多 关系,因此需要有一个关联表将 多对多 关系分割为 一对多 关系。 在我们的示例数据结构中,tbl_post_category 就是用于此目的的。在 AR 术语中,我们可以解释 MANY_MANY 为 BELONGS_TO 和 HAS_MANY 的组合。 例如,Post 属于多个(belongs to many) Category ,Category 有多个(has many) Post.本例还是使用 Chinook 数据库,修改 Yii Framework 开发教程(27) 数据库-关联 Active Record 示例。数据表之间的关系如下:CodeSmith 中 PLINQO-NH 代码位置:缺省目录为 C:\Program Files (x86)\CodeSmith\v6.5\Samples\Templates\Frameworks\PLINQO-NHCodeSmith.SchemaHelper 定义的主要类有:几个主要的类为EntityManager 管理所有的 Entity(对应于整个数据库)Entity 实体类(对应到单个表,视图)IAssoication 关系(定义表和表之间的关系)AssoicationType 关系的类型 (见下表)根据 AssociationType ,数据库之间的关系以及 Yii AR 支持的几种关系,可以定义下表:整个模板也是采用主-从模板的方式,主模板枚举 EntityManager 中的每个 Entity,然后调用子模板为每个表生成 AR 类:public void Generate(){ EntityManager entityManager = CreateEntityManager(); foreach(IEntity entity in entityManager.Entities) { if (!(entity is CommandEntity)) { RenderEntity(entity); } }}...private void RenderEntity(IEntity entity){ string folder=@"../models/"; EntityTemplate entityTemplate = this.Create<EntityTemplate>(); entityTemplate.SourceEntity = entity; entityTemplate.RenderToFile(folder+entity.Name+".php", true);}子模板则根据每个 Entity 的 Assoications(关系属性)为 AR 生成 relations 函数,<?phpclass <%= SourceEntity.Name %> extends CActiveRecord{ public static function model($className=__CLASS__) { return parent::model($className); } public function tableName() { return '<%= SourceEntity.GetSafeName() %>'; } <%if (SourceEntity.Associations.Count>0){ %> public function relations() { return array( <% IEnumerable<IAssociation> associations = SourceEntity.Associations; %> <% foreach(IAssociation association in associations) { %> <% if(association.Entity.Name!=association.ForeignEntity.Name) {%> <% if (association.AssociationType == AssociationType.ManyToOne || association.AssociationType==AssociationType.ManyToZeroOrOne) { %> '<%= ToCameral(association.Name) %>'=>array(self::BELONGS_TO, '<%= association.ForeignEntity.Name %>', <%=GetBelongToKey(association) %> <% } %> <% if (association.AssociationType == AssociationType.OneToMany || association.AssociationType==AssociationType.ZeroOrOneToMany) { %> '<%= ToCameral(association.Name) %>'=>array(self::HAS_MANY, '<%= association.ForeignEntity.Name %>', <%=GetKey(association) %> <% } %> <% if (association.AssociationType == AssociationType.OneToOne || association.AssociationType==AssociationType.OneToZeroOrOne) { %> '<%= ToCameral(association.Name) %>'=>array(self::HAS_ONE, '<%= association.ForeignEntity.Name %>', <%=GetKey(association) %> <% } %> <% if (association.AssociationType == AssociationType.ManyToMany) { %> '<%= ToCameral(association.Name) %>'=>array(self::MANY_MANY, '<%= association.IntermediaryAssociation.Entity.Name %>', <%=GetManyToManyKey(association) %> <% } %> <% } %> <% } %> ); } <% } %>}?><script runat="template">public string ToCameral(string name){ return StringUtil.ToCamelCase(name); }public string GetKey(IAssociation association){ string retString=string.Empty; if(association.Properties.Count>1) { retString="array("; foreach (AssociationProperty associati

[1] [2]  下一页


CodeSmith 为 Yii Framework 创建生成 ActiveRecord 的代码模板