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

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

一、原理讲解


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


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


一看就知道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>

其中的代码模板分类

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

通过@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;

}

}


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

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

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

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

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


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


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


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

然后在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="返 回" onclick="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="返 回" onclick="history.go(-1)"/>

</div>

</form:form>

</c:otherwise>

</c:choose>

</body>

</html>


注意其中的name属性

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

在GenTable中是用list来装的

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


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


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


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


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


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


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


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


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


如果是1的话就生成代码


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


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/>";

}

}


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

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



版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/101307.html原文链接:https://javaforall.net

(0)
上一篇 2021年6月16日 下午7:00
下一篇 2021年6月16日 下午8:00


相关推荐

  • python编写淘宝秒杀脚本

    python编写淘宝秒杀脚本最近想抢冰墩墩的手办和钥匙圈,但是同志们抢的速度太快了,无奈,还是自己写脚本吧。添加火狐浏览器插件Omnibug是一个插件,可以简化web度量实现的开发。检查每个传出请求(由浏览器发送)的模式;如果出现匹配,URL将显示在开发人员工具面板中,并进行解码以显示请求的详细信息。在火狐浏览器的插件中直接搜索、下载即可安装geckodriver在python中使用selenium爬取动态渲染网页,这个过程之中需要安装浏览器驱动geckodrivergeckodrivergithub链接将下载后到

    2022年6月9日
    31
  • Mac安装 yarn

    Mac安装 yarnMac安装yarnMac安装yarn一、按照提示安装gcc二、解决gcc错误的方法三、安装yarn四、配置VPN后,再次安装yarn五、下载yarn的tar.gz包,进行离线安装。Mac安装yarnMac升级到10.15.4之后,Xcode也升级到Version11.4.1(11E503a),终端下执行brewinstallyarn进行yarn安装,最后报错gcc错误。…

    2022年5月9日
    736
  • LangChain 智能体Agent

    LangChain 智能体Agent

    2026年3月16日
    2
  • Qtime定义(手工废物利用简单好看)

    QTime::QTime()默认构造函数,构造一个时,分,秒都为0的时间,如00:00:00.000(午夜)QTime::QTime(inth,intm,ints=0,intms=0)构造一个用户指定时,分,秒的时间.其参数有效值为:h:0–23m:0–59ms:0–999QTimeQTime::addMSecs(intms)const返回一个当前时间对象之后或之前m…

    2022年4月10日
    53
  • 认识Serverlet

    认识Serverlet认识和熟悉 ServletServl Server let 服务器小程序一个 Servlet 就是一个服务器端的 java 小程序 用于处理请求 生成动态响应 一个 Servlet 用于处理某种请求 如登录请求 注册请求创建 Servlet 就是创建 Servlet 类每个 web 应用程序都有一个而且只有一个全局的配置文件 叫做 web xml 用于配置程序的所有信息 如配置 servlet 每个 Servle

    2026年3月17日
    2
  • 黄仁勋第三次访华:英伟达4万亿市值血洗AI算力焦虑;DeepSeek爆火后遭遇滑铁卢;Manus大撤退!|混沌AI一周焦点

    黄仁勋第三次访华:英伟达4万亿市值血洗AI算力焦虑;DeepSeek爆火后遭遇滑铁卢;Manus大撤退!|混沌AI一周焦点

    2026年3月12日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号