jeesite快速开发平台(七)----代码生成原理

一、原理讲解


jeesite代码生成用的是FreeMarker模板引擎结合xml技术来实现的,定义的模板都放在resources/templates/modules/gen下




一看就知道crud就是基本的增删改查,dao是数据库操作,treetable是有关树方面的模板,其中主要的配置文件就是config.xml,该文件中定义了生成的模板,以及java类型,查询类型,字段显示类型等一些数据。

<?xml version="1.0" encoding="utf-8"?>
<config>
	<!-- 生成分类 -->
	<category>
		<category value="curd" label="增删改查(单表)">
			<template>curd/controller.xml</template>
			<template>curd/service.xml</template>
			<template>category-ref:dao</template>
			<template>curd/viewForm.xml</template>
			<template>curd/viewList.xml</template>
		</category>
		<category value="curd_many" label="增删改查(一对多)">
			<template>curd/controller.xml</template>
			<template>curd/serviceMany.xml</template>
			<template>category-ref:dao</template>
			<template>curd/viewFormMany.xml</template>
			<template>curd/viewList.xml</template>
			<childTable>
				<template>category-ref:dao</template>
			</childTable>
		</category>
		<category value="dao" label="仅持久层(dao/entity/mapper)">
			<template>dao/dao.xml</template>
			<template>dao/entity.xml</template>
			<template>dao/mapper.xml</template>
		</category>
		<category value="treeTable" label="树结构表(一体)">
			<template>treetable/controller.xml</template>
			<template>treetable/service.xml</template>
			<template>treetable/dao.xml</template>
			<template>treetable/entity.xml</template>
			<template>treetable/mapper.xml</template>
			<template>treetable/viewForm.xml</template>
			<template>treetable/viewList.xml</template>
		</category>
		<category value="treeTableAndList" label="树结构表(左树右表)">
			<template>category-ref:dao</template>
		</category>
	</category>
	<!-- java类型 -->
	<javaType>
		<dict value="String" label="String"/>
		<dict value="Long" label="Long"/>
		<dict value="Integer" label="Integer"/>
		<dict value="Double" label="Double"/>
		<dict value="java.util.Date" label="Date"/>
		<dict value="com.thinkgem.jeesite.modules.sys.entity.User" label="User"/>
		<dict value="com.thinkgem.jeesite.modules.sys.entity.Office" label="Office"/>
		<dict value="com.thinkgem.jeesite.modules.sys.entity.Area" label="Area"/>
		<dict value="This" label="ThisObj" description="生成当前对象"/>
		<dict value="Custom" label="Custom" description="自定义对象,生成后手动设置"/>
	</javaType>
	<!-- 查询类型 -->
	<queryType>
		<dict value="=" label="="/>
		<dict value="!=" label="!="/>
		<dict value=">" label=">"/>
		<dict value=">=" label=">="/>
		<dict value="<" label="<"/>
		<dict value="<=" label="<="/>
		<dict value="between" label="Between"/>
		<dict value="like" label="Like"/>
		<dict value="left_like" label="Left Like"/>
		<dict value="right_like" label="Right Like"/>
	</queryType>
	<!-- 字段显示类型 -->
	<showType>
		<dict value="input" label="单行文本"/>
		<dict value="textarea" label="多行文本"/>
		<dict value="select" label="下拉选项"/>
		<dict value="radiobox" label="单选按钮"/>
		<dict value="checkbox" label="复选框"/>
		<dict value="dateselect" label="日期选择"/>
		<dict value="userselect" label="人员选择"/>
		<dict value="officeselect" label="部门选择"/>
		<dict value="areaselect" label="区域选择"/>
		<dict value="treeselect" label="树选择控件"/>
		<dict value="fileselect" label="文件上传选择"/>
	</showType>
</config>

其中

<childTable>
	<template>category-ref:dao</template>
</childTable>

定义了子表,初看jeesite的代码生成,有个困惑的地方就是,一般通过FreeMarker进行代码生成定义的模板都是ftl格式的,而这里却是xml,什么鬼,难道这里不是用FreeMarker进行生成的??我们先来看下xml文件中的内容就清楚了:

<?xml version="1.0" encoding="utf-8"?>
<template>
	<name>controller</name>
	<filePath>src/main/java/${packageName}/${moduleName}/web/${subModuleName}</filePath>
	<fileName>${ClassName}Controller.java</fileName>
	<content><![CDATA[
/**
 * Copyright &copy; 2012-2016 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved.
 */
package ${packageName}.${moduleName}.web<#if subModuleName != "">.${subModuleName}</#if>;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.thinkgem.jeesite.common.config.Global;
import com.thinkgem.jeesite.common.persistence.Page;
import com.thinkgem.jeesite.common.web.BaseController;
import com.thinkgem.jeesite.common.utils.StringUtils;
import ${packageName}.${moduleName}.entity<#if subModuleName != "">.${subModuleName}</#if>.${ClassName};
import ${packageName}.${moduleName}.service<#if subModuleName != "">.${subModuleName}</#if>.${ClassName}Service;

/**
 * ${functionName}Controller
 * @author ${functionAuthor}
 * @version ${functionVersion}
 */
@Controller
@RequestMapping(value = "${r"${adminPath}"}/${urlPrefix}")
public class ${ClassName}Controller extends BaseController {

	@Autowired
	private ${ClassName}Service ${className}Service;
	
	@ModelAttribute
	public ${ClassName} get(@RequestParam(required=false) String id) {
		${ClassName} entity = null;
		if (StringUtils.isNotBlank(id)){
			entity = ${className}Service.get(id);
		}
		if (entity == null){
			entity = new ${ClassName}();
		}
		return entity;
	}
	
	@RequiresPermissions("${permissionPrefix}:view")
	@RequestMapping(value = {"list", ""})
	public String list(${ClassName} ${className}, HttpServletRequest request, HttpServletResponse response, Model model) {
		Page<${ClassName}> page = ${className}Service.findPage(new Page<${ClassName}>(request, response), ${className}); 
		model.addAttribute("page", page);
		return "${lastPackageName}/${viewPrefix}List";
	}

	@RequiresPermissions("${permissionPrefix}:view")
	@RequestMapping(value = "form")
	public String form(${ClassName} ${className}, Model model) {
		model.addAttribute("${className}", ${className});
		return "${lastPackageName}/${viewPrefix}Form";
	}

	@RequiresPermissions("${permissionPrefix}:edit")
	@RequestMapping(value = "save")
	public String save(${ClassName} ${className}, Model model, RedirectAttributes redirectAttributes) {
		if (!beanValidator(model, ${className})){
			return form(${className}, model);
		}
		${className}Service.save(${className});
		addMessage(redirectAttributes, "保存${functionNameSimple}成功");
		return "redirect:"+Global.getAdminPath()+"/${viewPrefix}/?repage";
	}
	
	@RequiresPermissions("${permissionPrefix}:edit")
	@RequestMapping(value = "delete")
	public String delete(${ClassName} ${className}, RedirectAttributes redirectAttributes) {
		${className}Service.delete(${className});
		addMessage(redirectAttributes, "删除${functionNameSimple}成功");
		return "redirect:"+Global.getAdminPath()+"/${viewPrefix}/?repage";
	}

}]]>
	</content>
</template>

其中的xml格式为:

<?xml version="1.0" encoding="utf-8"?>
<template>
	<name>controller</name>
	<filePath>src/main/java/${packageName}/${moduleName}/web/${subModuleName}</filePath>
	<fileName>${ClassName}Controller.java</fileName>
	<content><![CDATA[]]>
	</content>
</template>

发现其中的奥秘没,他把模板内容都放在了content标签的CDATA[]区。而且config.xml有相对应的bean,用来实现xml转对象:


/**
 * 生成方案Entity
 * @author ThinkGem
 * @version 2013-10-15
 */
@XmlRootElement(name="config")
public class GenConfig implements Serializable {
	
	private static final long serialVersionUID = 1L;
	private List<GenCategory> categoryList;	// 代码模板分类
	private List<Dict> javaTypeList;		// Java类型
	private List<Dict> queryTypeList;		// 查询类型
	private List<Dict> showTypeList;		// 显示类型

	public GenConfig() {
		super();
	}

	@XmlElementWrapper(name = "category")
	@XmlElement(name = "category")
	public List<GenCategory> getCategoryList() {
		return categoryList;
	}

	public void setCategoryList(List<GenCategory> categoryList) {
		this.categoryList = categoryList;
	}

	@XmlElementWrapper(name = "javaType")
	@XmlElement(name = "dict")
	public List<Dict> getJavaTypeList() {
		return javaTypeList;
	}

	public void setJavaTypeList(List<Dict> javaTypeList) {
		this.javaTypeList = javaTypeList;
	}

	@XmlElementWrapper(name = "queryType")
	@XmlElement(name = "dict")
	public List<Dict> getQueryTypeList() {
		return queryTypeList;
	}

	public void setQueryTypeList(List<Dict> queryTypeList) {
		this.queryTypeList = queryTypeList;
	}

	@XmlElementWrapper(name = "showType")
	@XmlElement(name = "dict")
	public List<Dict> getShowTypeList() {
		return showTypeList;
	}

	public void setShowTypeList(List<Dict> showTypeList) {
		this.showTypeList = showTypeList;
	}
	
}

其中的

private List<GenCategory> categoryList;	        // 代码模板分类
private List<Dict> javaTypeList;		// Java类型
private List<Dict> queryTypeList;		// 查询类型
private List<Dict> showTypeList;		// 显示类型

对应的就是xml中预先定义好的

<?xml version="1.0" encoding="utf-8"?>
<config>
	<!-- 生成分类 -->
	<category>
		<category value="curd" label="增删改查(单表)">
			<template>curd/controller.xml</template>
		    ....
		</category>
		<category value="curd_many" label="增删改查(一对多)">
			<template>curd/controller.xml</template>
			....
			<childTable>
				<template>category-ref:dao</template>
			</childTable>
		</category>
		<category value="dao" label="仅持久层(dao/entity/mapper)">
			<template>dao/dao.xml</template>
			....
		</category>
		<category value="treeTable" label="树结构表(一体)">
			<template>treetable/controller.xml</template>
			....
		</category>
		<category value="treeTableAndList" label="树结构表(左树右表)">
			<template>category-ref:dao</template>
		</category>
	</category>
	<!-- java类型 -->
	<javaType>
		<dict value="String" label="String"/>
		....
	</javaType>
	<!-- 查询类型 -->
	<queryType>
		<dict value="=" label="="/>
		....
	</queryType>
	<!-- 字段显示类型 -->
	<showType>
		<dict value="input" label="单行文本"/>
		<dict value="textarea" label="多行文本"/>
		....
	</showType>
</config>


其中的代码模板分类


通过@XmlElement(name = "category")引用了GenCategory类,其中定义了主子模板

/**
 * 生成方案Entity
 * @author ThinkGem
 * @version 2013-10-15
 */
@XmlRootElement(name="category")
public class GenCategory extends Dict {
	
	private static final long serialVersionUID = 1L;
	private List<String> template;			// 主表模板
	private List<String> childTableTemplate;// 子表模板
	
	public static String CATEGORY_REF = "category-ref:";

	public GenCategory() {
		super();
	}

	@XmlElement(name = "template")
	public List<String> getTemplate() {
		return template;
	}

	public void setTemplate(List<String> template) {
		this.template = template;
	}
	
	@XmlElementWrapper(name = "childTable")
	@XmlElement(name = "template")
	public List<String> getChildTableTemplate() {
		return childTableTemplate;
	}

	public void setChildTableTemplate(List<String> childTableTemplate) {
		this.childTableTemplate = childTableTemplate;
	}
	
}

这两个主子其实对应的就是




在GenUtils中通过getConfig()方法可获取转换成bean的对象




而其中的数据就是在配置业务表是初始化的一些数据,比如当我们选择某一张表时,然后点击下一步




就会调用GenTableController中的form方法,把一些配置参数设置进去



然后在genTableForm.jsp页面进行渲染

<%@ page contentType="text/html;charset=UTF-8" %>
<%@ include file="/WEB-INF/views/include/taglib.jsp"%>
<html>
<head>
	<title>业务表管理</title>
	<meta name="decorator" content="default"/>
	<script type="text/javascript">
		$(document).ready(function() {
			$("#comments").focus();
			$("#inputForm").validate({
				submitHandler: function(form){
					loading('正在提交,请稍等...');
					$("input[type=checkbox]").each(function(){
						$(this).after("<input type=\"hidden\" name=\""+$(this).attr("name")+"\" value=\""
								+($(this).attr("checked")?"1":"0")+"\"/>");
						$(this).attr("name", "_"+$(this).attr("name"));
					});
					form.submit();
				},
				errorContainer: "#messageBox",
				errorPlacement: function(error, element) {
					$("#messageBox").text("输入有误,请先更正。");
					if (element.is(":checkbox")||element.is(":radio")||element.parent().is(".input-append")){
						error.appendTo(element.parent().parent());
					} else {
						error.insertAfter(element);
					}
				}
			});
		});
	</script>
</head>
<body>
	<ul class="nav nav-tabs">
		<li><a href="${ctx}/gen/genTable/">业务表列表</a></li>
		<li class="active"><a href="${ctx}/gen/genTable/form?id=${genTable.id}&name=${genTable.name}">业务表<shiro:hasPermission name="gen:genTable:edit">${not empty genTable.id?'修改':'添加'}</shiro:hasPermission><shiro:lacksPermission name="gen:genTable:edit">查看</shiro:lacksPermission></a></li>
	</ul>
	<c:choose>
		<c:when test="${empty genTable.name}">
			<form:form id="inputForm" modelAttribute="genTable" action="${ctx}/gen/genTable/form" method="post" class="form-horizontal">
				<form:hidden path="id"/>
				<sys:message content="${message}"/>
				<br/>
				<div class="control-group">
					<label class="control-label">表名:</label>
					<div class="controls">
						<form:select path="name" class="input-xxlarge">
							<form:options items="${tableList}" itemLabel="nameAndComments" itemValue="name" htmlEscape="false"/>
						</form:select>
					</div>
					<div class="form-actions">
						<input id="btnSubmit" class="btn btn-primary" type="submit" value="下一步"/> 
						<input id="btnCancel" class="btn" type="button" value="返 回" οnclick="history.go(-1)"/>
					</div>
				</div>
			</form:form>
		</c:when>
		<c:otherwise>
			<form:form id="inputForm" modelAttribute="genTable" action="${ctx}/gen/genTable/save" method="post" class="form-horizontal">
				<form:hidden path="id"/>
				<sys:message content="${message}"/>
				<fieldset>
					<legend>基本信息</legend>
					<div class="control-group">
						<label class="control-label">表名:</label>
						<div class="controls">
							<form:input path="name" htmlEscape="false" maxlength="200" class="required" readonly="true"/>
						</div>
					</div>
					<div class="control-group">
						<label class="control-label">说明:</label>
						<div class="controls">
							<form:input path="comments" htmlEscape="false" maxlength="200" class="required"/>
						</div>
					</div>
					<div class="control-group">
						<label class="control-label">类名:</label>
						<div class="controls">
							<form:input path="className" htmlEscape="false" maxlength="200" class="required"/>
						</div>
					</div>
					<div class="control-group">
						<label class="control-label">父表表名:</label>
						<div class="controls">
							<form:select path="parentTable" cssClass="input-xlarge">
								<form:option value="">无</form:option>
								<form:options items="${tableList}" itemLabel="nameAndComments" itemValue="name" htmlEscape="false"/>
							</form:select>
							 当前表外键:
							<form:select path="parentTableFk" cssClass="input-xlarge">
								<form:option value="">无</form:option>
								<form:options items="${genTable.columnList}" itemLabel="nameAndComments" itemValue="name" htmlEscape="false"/>
							</form:select>
							<span class="help-inline">如果有父表,请指定父表表名和外键</span>
						</div>
					</div>
					<div class="control-group hide">
						<label class="control-label">备注:</label>
						<div class="controls">
							<form:textarea path="remarks" htmlEscape="false" rows="4" maxlength="200" class="input-xxlarge"/>
						</div>
					</div>
					<legend>字段列表</legend>
					<div class="control-group">
						<table id="contentTable" class="table table-striped table-bordered table-condensed">
							<thead><tr>
								<th title="数据库字段名">列名</th>
								<th title="默认读取数据库字段备注">说明</th>
								<th title="数据库中设置的字段类型及长度">物理类型</th>
								<th title="实体对象的属性字段类型">Java类型</th>
								<th title="实体对象的属性字段(对象名.属性名|属性名2|属性名3,例如:用户user.id|name|loginName,属性名2和属性名3为Join时关联查询的字段)">Java属性名称 <i class="icon-question-sign"></i></th>
								<th title="是否是数据库主键">主键</th><th title="字段是否可为空值,不可为空字段自动进行空值验证">可空</th><th title="选中后该字段被加入到insert语句里">插入</th>
								<th title="选中后该字段被加入到update语句里">编辑</th><th title="选中后该字段被加入到查询列表里">列表</th>
								<th title="选中后该字段被加入到查询条件里">查询</th><th title="该字段为查询字段时的查询匹配放松">查询匹配方式</th>
								<th title="字段在表单中显示的类型">显示表单类型</th><th title="显示表单类型设置为“下拉框、复选框、点选框”时,需设置字典的类型">字典类型</th><th>排序</th></tr></thead>
							<tbody>
							<c:forEach items="${genTable.columnList}" var="column" varStatus="vs">
								<tr${column.delFlag eq '1'?' class="error" title="已删除的列,保存之后消失!"':''}>
									<td nowrap>
										<input type="hidden" name="columnList[${vs.index}].id" value="${column.id}"/>
										<input type="hidden" name="columnList[${vs.index}].delFlag" value="${column.delFlag}"/>
										<input type="hidden" name="columnList[${vs.index}].genTable.id" value="${column.genTable.id}"/>
										<input type="hidden" name="columnList[${vs.index}].name" value="${column.name}"/>${column.name}
									</td>
									<td>
										<input type="text" name="columnList[${vs.index}].comments" value="${column.comments}" maxlength="200" class="required" style="width:100px;"/>
									</td>
									<td nowrap>
										<input type="hidden" name="columnList[${vs.index}].jdbcType" value="${column.jdbcType}"/>${column.jdbcType}
									</td>
									<td>
										<select name="columnList[${vs.index}].javaType" class="required input-mini" style="width:85px;*width:75px">
											<c:forEach items="${config.javaTypeList}" var="dict">
												<option value="${dict.value}" ${dict.value==column.javaType?'selected':''} title="${dict.description}">${dict.label}</option>
											</c:forEach>
										</select>
									</td>
									<td>
										<input type="text" name="columnList[${vs.index}].javaField" value="${column.javaField}" maxlength="200" class="required input-small"/>
									</td>
									<td>
										<input type="checkbox" name="columnList[${vs.index}].isPk" value="1" ${column.isPk eq '1' ? 'checked' : ''}/>
									</td>
									<td>
										<input type="checkbox" name="columnList[${vs.index}].isNull" value="1" ${column.isNull eq '1' ? 'checked' : ''}/>
									</td>
									<td>
										<input type="checkbox" name="columnList[${vs.index}].isInsert" value="1" ${column.isInsert eq '1' ? 'checked' : ''}/>
									</td>
									<td>
										<input type="checkbox" name="columnList[${vs.index}].isEdit" value="1" ${column.isEdit eq '1' ? 'checked' : ''}/>
									</td>
									<td>
										<input type="checkbox" name="columnList[${vs.index}].isList" value="1" ${column.isList eq '1' ? 'checked' : ''}/>
									</td>
									<td>
										<input type="checkbox" name="columnList[${vs.index}].isQuery" value="1" ${column.isQuery eq '1' ? 'checked' : ''}/>
									</td>
									<td>
										<select name="columnList[${vs.index}].queryType" class="required input-mini">
											<c:forEach items="${config.queryTypeList}" var="dict">
												<option value="${fns:escapeHtml(dict.value)}" ${fns:escapeHtml(dict.value)==column.queryType?'selected':''} title="${dict.description}">${fns:escapeHtml(dict.label)}</option>
											</c:forEach>
										</select>
									</td>
									<td>
										<select name="columnList[${vs.index}].showType" class="required" style="width:100px;">
											<c:forEach items="${config.showTypeList}" var="dict">
												<option value="${dict.value}" ${dict.value==column.showType?'selected':''} title="${dict.description}">${dict.label}</option>
											</c:forEach>
										</select>
									</td>
									<td>
										<input type="text" name="columnList[${vs.index}].dictType" value="${column.dictType}" maxlength="200" class="input-mini"/>
									</td>
									<td>
										<input type="text" name="columnList[${vs.index}].sort" value="${column.sort}" maxlength="200" class="required input-min digits"/>
									</td>
								</tr>
							</c:forEach>
							</tbody>
						</table>
					</div>
				</fieldset>
				<div class="form-actions">
					<shiro:hasPermission name="gen:genTable:edit"><input id="btnSubmit" class="btn btn-primary" type="submit" value="保 存"/> </shiro:hasPermission>
					<input id="btnCancel" class="btn" type="button" value="返 回" οnclick="history.go(-1)"/>
				</div>
			</form:form>
		</c:otherwise>
	</c:choose>
</body>
</html>

注意其中的name属性

name="columnList[${vs.index}].xxx"


在GenTable中是用list来装的


所以在spring mvc数据绑定的时候可以通过下标的形式来传值




业务表配置好之后,就是生成代码,新建生成方案配置,然后输入一些必须的信息




点击保存并生成代码,会调用GenSchemeController中的save()方法,传入一些参数




然后调用genSchemeService.save()方法进行生成




如果是1的话就生成代码




generateCode方法如下:

	private String generateCode(GenScheme genScheme){

		StringBuilder result = new StringBuilder();
		
		// 查询主表及字段列
		GenTable genTable = genTableDao.get(genScheme.getGenTable().getId());
		genTable.setColumnList(genTableColumnDao.findList(new GenTableColumn(new GenTable(genTable.getId()))));
		
		// 获取所有代码模板
		GenConfig config = GenUtils.getConfig();
		
		// 获取模板列表
		List<GenTemplate> templateList = GenUtils.getTemplateList(config, genScheme.getCategory(), false); //获取所有不包含childTableTemplateList的数据
		List<GenTemplate> childTableTemplateList = GenUtils.getTemplateList(config, genScheme.getCategory(), true);
		
		// 如果有子表模板,则需要获取子表列表
		if (childTableTemplateList.size() > 0){
			GenTable parentTable = new GenTable();
			parentTable.setParentTable(genTable.getName());
			genTable.setChildList(genTableDao.findList(parentTable));
		}
		
		// 生成子表模板代码
		for (GenTable childTable : genTable.getChildList()){
			childTable.setParent(genTable);
			childTable.setColumnList(genTableColumnDao.findList(new GenTableColumn(new GenTable(childTable.getId()))));
			genScheme.setGenTable(childTable);
			Map<String, Object> childTableModel = GenUtils.getDataModel(genScheme);
			for (GenTemplate tpl : childTableTemplateList){
				result.append(GenUtils.generateToFile(tpl, childTableModel, genScheme.getReplaceFile()));
			}
		}
		
		// 生成主表模板代码
		genScheme.setGenTable(genTable);
		Map<String, Object> model = GenUtils.getDataModel(genScheme);
		for (GenTemplate tpl : templateList){
			result.append(GenUtils.generateToFile(tpl, model, genScheme.getReplaceFile()));
		}
		return result.toString();
	}

该方法主要是做一些,获取模板,然后进行数据绑定等一些工作。其中的

// 获取模板列表
List<GenTemplate> templateList = GenUtils.getTemplateList(config, genScheme.getCategory(), false); //获取所有不包含childTableTemplateList的数据
List<GenTemplate> childTableTemplateList = GenUtils.getTemplateList(config, genScheme.getCategory(), true); 

getTemplateList方法为

	/**
	 * 根据分类获取模板列表
	 * @param config
	 * @param category
	 * @param isChildTable 是否是子表
	 * @return
	 */
	public static List<GenTemplate> getTemplateList(GenConfig config, String category, boolean isChildTable){
		List<GenTemplate> templateList = Lists.newArrayList();
		if (config !=null && config.getCategoryList() != null && category !=  null){
			for (GenCategory e : config.getCategoryList()){
				if (category.equals(e.getValue())){
					List<String> list = null;
					if (!isChildTable){
						list = e.getTemplate();
					}else{
						list = e.getChildTableTemplate();
					}
					if (list != null){
						for (String s : list){
							if (StringUtils.startsWith(s, GenCategory.CATEGORY_REF)){
								templateList.addAll(getTemplateList(config, StringUtils.replace(s, GenCategory.CATEGORY_REF, ""), false));
							}else{
								GenTemplate template = fileToObject(s, GenTemplate.class);
								if (template != null){
									templateList.add(template);
								}
							}
						}
					}
					break;
				}
			}
		}
		return templateList;
	}
	

通过标志位来获取

if (!isChildTable){
	list = e.getTemplate();
}else{
	list = e.getChildTableTemplate();
}
主表,子表模板, 生成文件的方法是GenUtils.generateToFile(tpl, model, genScheme.getReplaceFile())

	/**
	 * 生成到文件
	 * @param tpl
	 * @param model
	 * @param isReplaceFile
	 * @return
	 */
	public static String generateToFile(GenTemplate tpl, Map<String, Object> model, boolean isReplaceFile){
		// 获取生成文件
		String fileName = Global.getProjectPath() + File.separator 
				+ StringUtils.replaceEach(FreeMarkers.renderString(tpl.getFilePath() + "/", model), 
						new String[]{"//", "/", "."}, new String[]{File.separator, File.separator, File.separator})
				+ FreeMarkers.renderString(tpl.getFileName(), model);
		logger.debug(" fileName === " + fileName);

		// 获取生成文件内容
		String content = FreeMarkers.renderString(StringUtils.trimToEmpty(tpl.getContent()), model);
		logger.debug(" content === \r\n" + content);
		
		// 如果选择替换文件,则删除原文件
		if (isReplaceFile){
			FileUtils.deleteFile(fileName);
		}
		
		// 创建并写入文件
		if (FileUtils.createFile(fileName)){
			FileUtils.writeToFile(fileName, content, true);
			logger.debug(" file create === " + fileName);
			return "生成成功:"+fileName+"<br/>";
		}else{
			logger.debug(" file extents === " + fileName);
			return "文件已存在:"+fileName+"<br/>";
		}
	}

生成成功之后,会有如下提示:




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值