T4模版生成SpringMVC构造REST代码:第三篇 用T4模版生成POCO类代码

        用T4模版生成POCO类代码,简单,但要求数据库定义一定要有规律,否则就没有实际意义了。这里,我们做如下规定:

       1、数据库的表名,全部小写,各个单词之间以“_”(下划线)分割,且第一个单词为前缀。

        2、表中各个字段,全部小写,各个单词之间以“_”(下划线)分割,表最好能够有create_time,create_by,update_time,update_time,version_no,is_valid。

        生成的POCO规定:

        1、类的名称,去掉前缀及分割符,各个单词的首字母大写,采用Pascial规范。

        2、类中属性的名称,去掉分割符,首字符小写其余大写,采用Camel规范。

        3、类中属性的数据类别,全部采用结构类型,且做以下转换

             A、sbyte、bool、boolean、int、integer、Integer、Int16、short、Int32、Nullable<sbyte>、Nullable<bool>、Nullable<boolean>、Nullable<int>、Nullable<integer>、Nullable<Integer>、Nullable<Int16>、Nullable<short>、Nullable<Int32>,全部转换成Integer

            B、long、Long、Nullable<long>、Nullable<Long>,全部转换成Long

            C、float、Float、decimal、Decimal、Nullable<float>、Nullable<Float>、Nullable<decimal>、Nullable<Decimal>,全部转换成Double

            D、string、String,全部转化成String

            E、date、time、datetime、timestamp、Nullable<date>、Nullable<time>、Nullable<datetime>、Nullable<timestamp>,全部转换成String;其实,多平台开发时,这些字段根本不应该出现,直接用时间戳(当前百万秒-1970-1-1 00:00:00)

           F、byte[]二进制数据,不变

          备 注:

                 A、text,在EntityFramework(简称EF)中,已经转化成String,长度max(2GB);

                 B、binary、blob、mediumblob、tinyblob、varbinary,在EF中已经转换成byte[]

          下面,我们开始用T4模版生成POCO类代码之旅

第一步,在“解决方案JavaGenerate”中添加类库,用于存放model的模版及相应文件,我们命名这个类库为JavaModels

             点击“解决方案JavaGenerate”,右键,选择“添加 ”--〉“新建项目”,再选择"类库",名称中输入JavaModels。返回后,在“解决方案JavaGenerate”中增加了一个叫JavaModels的项目,且自带了一个class.cs的类,我们点击它,再点右键删除它,不用它。如图3-1,注意红色方框,特别是要选中.NET Framework4

T4模版生成SpringMVC构造REST代码:第三篇 用T4模版生成POCO类代码_第1张图片

图3-1

第二步,增加t4空模版

             在解决方案管理器中,选择JavaModels项目,点击右键,选择“添加 ”--〉“新建项”,在弹出的窗体中做图3-2的选择和输入项。

T4模版生成SpringMVC构造REST代码:第三篇 用T4模版生成POCO类代码_第2张图片

图3-2

第三步,修改模版,我直接贴一个,然后慢慢解释

<#@ template language="C#" debug="false" hostspecific="true"#>
<#@ include file="EF.Utility.CS.ttinclude"#>
<#@ assembly name="EnvDTE" #>
<#@ import namespace="EnvDTE"#>
<#@
 output extension=".cs"#><#
CodeGenerationTools code = new CodeGenerationTools(this);
MetadataLoader loader = new MetadataLoader(this);
CodeRegion region = new CodeRegion(this, 1);
MetadataTools ef = new MetadataTools(this);
string inputFile = @"..\EDMX\dblxh.edmx";//EDMX项目中dblxh.edmx的路径,根据项目修改

MetadataWorkspace metadataWorkspace = null;
bool allMetadataLoaded =loader.TryLoadAllMetadata(inputFile, out metadataWorkspace);
EdmItemCollection ItemCollection = (EdmItemCollection)metadataWorkspace.GetItemCollection(DataSpace.CSpace);

EntityFrameworkTemplateFileManager fileManager = EntityFrameworkTemplateFileManager.Create(this);

// 发出文件
foreach (EntityType entity in ItemCollection.GetItems<EntityType>().OrderBy(e => e.Name))
{	
	string filePascialName=getModelsPascialName(entity.Name);//Pascial风格的类名称
	string fileCamelName=getModelsCamelName(entity.Name);//Camel风格的类名称
	
    fileManager.StartNewFile(filePascialName+ ".java");//输出的类文件名称,及开始输出文件
#>
package com.jiahe.rest.demo2.models;
/*********************************************************************************
 * Copyright (c) ZDSOFT LIMITED  2012 All Rights Reserved
 * 系统名称:
 * 程序模块文件名称:<#=filePascialName+ ".java"#>
 * 摘要:
*********************************************************************************/

import java.io.Serializable;

/*********************************************************************************
 * 
 * <pre>
 * [版本说明]
 * 1.0    2012/08/30   初版
 * </pre>
 *  @version  1.0 2013/5/16
 *  @author   lxh
 *********************************************************************************/
public class <#=filePascialName#> implements Serializable	{

	private static final long serialVersionUID = 1L;

<#
//定义实体的私有属性
//循环实体的每一个属性
//getPropertyType,得到属性的数据类型
//getPropertyCamelName 得到属性的Camel风格的名称
foreach (EdmProperty edmProperty in entity.Properties.Where(p => p.TypeUsage.EdmType is PrimitiveType && p.DeclaringType == entity))
{
#>
	private <#=getPropertyType(code.Escape(edmProperty.TypeUsage))#> <#=getPropertyCamelName(edmProperty.Name)#>;
<#}#>

<#
//定义实体私有属性的get/set
//循环实体的每一个属性
//getPropertyType,得到属性的数据类型
//getPropertyCamelName 得到属性的Camel风格的名称
//getPropertyPascialName 得到属性的Pascial风格的名称
foreach (EdmProperty edmProperty in entity.Properties.Where(p => p.TypeUsage.EdmType is PrimitiveType && p.DeclaringType == entity))
{#>

	public void set<#=getPropertyPascialName(edmProperty.Name)#>(<#=getPropertyType(code.Escape(edmProperty.TypeUsage))#> <#=getPropertyCamelName(edmProperty.Name)#>)
	{
		this.<#=getPropertyCamelName(edmProperty.Name)#>=<#=getPropertyCamelName(edmProperty.Name)#>;
	}
	public <#=getPropertyType(code.Escape(edmProperty.TypeUsage))#> get<#=getPropertyPascialName(edmProperty.Name)#>()
	{
		return this.<#=getPropertyCamelName(edmProperty.Name)#>;
	}
<#}#>
<#
//定义实体的toString
//循环实体的每一个属性
//getPropertyType,得到属性的数据类型
//getPropertyCamelName 得到属性的Camel风格的名称
//getPropertyPascialName 得到属性的Pascial风格的名称
string toStr=string.Empty;
foreach (EdmProperty edmProperty in entity.Properties.Where(p => p.TypeUsage.EdmType is PrimitiveType && p.DeclaringType == entity))
toStr+="+ \", "+getPropertyCamelName(edmProperty.Name)+"=\"+"+getPropertyCamelName(edmProperty.Name);
toStr=toStr.Substring(4);
#>
	@Override
	public String toString() {
		return "<#=filePascialName#> [<#= toStr #> + "]";
	}
<# 
//定义默认构造函数
#>
	public <#=filePascialName#>() {
		super();
	}
<# 
//定义参数构造函数
toStr=string.Empty;
foreach (EdmProperty edmProperty in entity.Properties.Where(p => p.TypeUsage.EdmType is PrimitiveType && p.DeclaringType == entity))
toStr+=getPropertyType(code.Escape(edmProperty.TypeUsage))+" "+getPropertyCamelName(edmProperty.Name);
#>
	public <#=filePascialName#>(<#=toStr#>)
	{
		super();
<#foreach (EdmProperty edmProperty in entity.Properties.Where(p => p.TypeUsage.EdmType is PrimitiveType && p.DeclaringType == entity)){#>
		this.<#= getPropertyCamelName(edmProperty.Name)#>=<#=getPropertyCamelName(edmProperty.Name)#>;
<#}#>
	}
<#
}
fileManager.Process();
#>
<#+
//得到类的Pascial风格名称
string getModelsPascialName(string source)
{
	string[] s=source.Split('_');
	for(int i=0;i<s.Length;i++)
	{
		string s1=s[i].Substring(0,1).ToUpper();
		string s2=s[i].Substring(1);
		s[i]=string.Concat(s1,s2);
    }

	string result=string.Empty;
	for(int i=1;i<s.Length;i++)
	{
		result=string.Concat(result,s[i]);
	}
	return result;	
}
#>
<#+
//得到类的Camel风格名称
string getModelsCamelName(string source)
{
	string[] s=source.Split('_');
	for(int i=0;i<s.Length;i++)
	{
		string s1=s[i].Substring(0,1).ToUpper();
		string s2=s[i].Substring(1);
		s[i]=string.Concat(s1,s2);
    }

	string result=string.Empty;
	for(int i=1;i<s.Length;i++)
	{
		result=string.Concat(result,s[i]);
	}
	string s11=result.Substring(0,1).ToLower();
	string s12=result.Substring(1);
	return string.Concat(s11,s12);
}
#>
<#+
//得到属性的Pascial风格名称
string getPropertyPascialName(string source)
{
	string[] s=source.Split('_');
	for(int i=0;i<s.Length;i++)
	{
		string s1=s[i].Substring(0,1).ToUpper();
		string s2=s[i].Substring(1);
		s[i]=string.Concat(s1,s2);
    }
	return string.Concat(s);	
}
//得到属性的Camel风格名称
string getPropertyCamelName(string source)
{
	string[] s=source.Split('_');
	for(int i=0;i<s.Length;i++)
	{
		string s1=s[i].Substring(0,1).ToUpper();
		string s2=s[i].Substring(1);
		s[i]=string.Concat(s1,s2);
    }
	string result=string.Concat(s);
	string s11=result.Substring(0,1).ToLower();
	string s12=result.Substring(1);
	return string.Concat(s11,s12);
}
//数据类型转换
string getPropertyType(string source)
{
	string result=string.Empty;

	if (source=="int") result="Integer";
	if (source=="integer") result="Integer";
	if (source=="Integer") result="Integer";	
	if (source=="byte") result="Integer";	
	if (source=="sbyte") result="Integer";
	if (source=="bool") result="Integer";
	if (source=="Int16") result="Integer";
	if (source=="short") result="Integer";
	if (source=="Int32") result="Integer";


	if (source=="Nullable<int>") result="Integer";
	if (source=="Nullable<integer>") result="Integer";
	if (source=="Nullable<Integer>") result="Integer";	
	if (source=="Nullable<byte>") result="Integer";	
	if (source=="Nullable<sbyte>") result="Integer";
	if (source=="Nullable<bool>") result="Integer";
	if (source=="Nullable<boolean>") result="Integer";
	if (source=="Nullable<Int16>") result="Integer";
	if (source=="Nullable<short>") result="Integer";
	if (source=="Nullable<Int32>") result="Integer";

	if (source=="Int64") result="Long";
	if (source=="long") result="Long";
	if (source=="Long") result="Long";

	if (source=="Nullable<Int64>") result="Long";
	if (source=="Nullable<long>") result="Long";
	if (source=="Nullable<Long>") result="Long";

	
	if (source=="float") result="Double";
	if (source=="Float") result="Double";
	if (source=="decimal") result="Double";
	if (source=="Decimal") result="Double";

	if (source=="Nullable<float>") result="Double";
	if (source=="Nullable<Float>") result="Double";
	if (source=="Nullable<decimal>") result="Double";
	if (source=="Nullable<Decimal>") result="Double";
	
	
	if (source=="byte[]") result="byte[]";
	
	
	if (source=="string") result="String";
	if (source=="String") result="String";

	if (source=="System.Date") result="String";
	if (source=="System.Time") result="String";
	if (source=="System.DateTime") result="String";

	if (source=="Nullable<System.Date>") result="String";
	if (source=="Nullable<System.Time>") result="String";
	if (source=="Nullable<System.DateTime>") result="String";
	
	return result;
}
#>
把上面模版拷贝到JavaModels.tt中,保存,没有报错就会在“解决方案资源管理器”看到JavaModels.tt下生成了各个model;报错,那么就是EDMX项目添加的时候没有注意框架选择,把EDMX项目删除,按照图3-1的样式建立EDMX,再建立ADO.NET实体数据模型就可以。

       

模版说明:

 一、标签符号说明

        1、标签实际只有一种,以<#开始,以#>结束。然后进行扩展,在<#开始再添加运算符就实现了不同的扩展。

         2、<#@.....#>,表示引用说明。基本是死的,不用记住,每次拷贝就行,其实望文就能生意。

         3、<#=tttt#>,表示取ttt的值。ttt,可以是一个变量,也可以是一个方法。

         4、<#+  ....#>,表示定义一个或一些方法。

         注意:标签不支持嵌套。多读几个模版,你就明白了。

二、模版结构

          1、模版基本由三个部分组成:引用部分,输入文件部分,公共方法部分。

          2、引用部分,除ADO.NET实体数据模型文件string inputFile = @"..\EDMX\dblxh.edmx";需要修改外,其余基本不用修改。

          3、输出文件部分,由于输出文件的不一致,基本都需要修改。

          4、公共部分,需要多少就写,只要会java,c++的,都能够编写,它基本参照c++的语法。

三、模版语法

        1、模版语法,是标准的C#语法,包括Linq的Lamada。lambda,java马上也支持,非常简单。

              例如:

              A、entity.Properties.Where(p => p.TypeUsage.EdmType is PrimitiveType && p.DeclaringType == entity)

                    表示对象entity集合查询出满足Properties.TypeUsage.EdmType is PrimitiveType且Properties.DeclaringType == entity的子集。

                     在EF模版中,这个表达式是查询出实体类的本来属性。

             B、ItemCollection.GetItems<EntityType>().OrderBy(e => e.Name)

                   表示对集合按照name排序.在EF中,表示获得所有的实体类且按名称排序。

         2、标签符号内的内容,不输出到文件,其余的按照顺序依次输出。把上面的javamodels.tt文件和输出的XXXX.java文件对比,就明白。

                       



你可能感兴趣的:(springMVC,REST,T4模版)