JEESITE快速開發平臺(七)代碼生成原理

一、原理講解

 

jeesite代碼生成用的是FreeMarker模板引擎結合xml技術來實現的,定義的模板都放在resources/templates/modules/gen下

 

 

一看就知道crud就是基本的增刪改查,dao是數據庫操作,treetable是有關樹方面的模板,其中主要的配置文件就是config.xml,該文件中定義了生成的模板,以及java類型,查詢類型,字段顯示類型等一些數據。

 

[html] view plain copy

 

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <config>  
  3.     <!-- 生成分類 -->  
  4.     <category>  
  5.         <category value="curd" label="增刪改查(單表)">  
  6.             <template>curd/controller.xml</template>  
  7.             <template>curd/service.xml</template>  
  8.             <template>category-ref:dao</template>  
  9.             <template>curd/viewForm.xml</template>  
  10.             <template>curd/viewList.xml</template>  
  11.         </category>  
  12.         <category value="curd_many" label="增刪改查(一對多)">  
  13.             <template>curd/controller.xml</template>  
  14.             <template>curd/serviceMany.xml</template>  
  15.             <template>category-ref:dao</template>  
  16.             <template>curd/viewFormMany.xml</template>  
  17.             <template>curd/viewList.xml</template>  
  18.             <childTable>  
  19.                 <template>category-ref:dao</template>  
  20.             </childTable>  
  21.         </category>  
  22.         <category value="dao" label="僅持久層(dao/entity/mapper)">  
  23.             <template>dao/dao.xml</template>  
  24.             <template>dao/entity.xml</template>  
  25.             <template>dao/mapper.xml</template>  
  26.         </category>  
  27.         <category value="treeTable" label="樹結構表(一體)">  
  28.             <template>treetable/controller.xml</template>  
  29.             <template>treetable/service.xml</template>  
  30.             <template>treetable/dao.xml</template>  
  31.             <template>treetable/entity.xml</template>  
  32.             <template>treetable/mapper.xml</template>  
  33.             <template>treetable/viewForm.xml</template>  
  34.             <template>treetable/viewList.xml</template>  
  35.         </category>  
  36.         <category value="treeTableAndList" label="樹結構表(左樹右表)">  
  37.             <template>category-ref:dao</template>  
  38.         </category>  
  39.     </category>  
  40.     <!-- java類型 -->  
  41.     <javaType>  
  42.         <dict value="String" label="String"/>  
  43.         <dict value="Long" label="Long"/>  
  44.         <dict value="Integer" label="Integer"/>  
  45.         <dict value="Double" label="Double"/>  
  46.         <dict value="java.util.Date" label="Date"/>  
  47.         <dict value="com.thinkgem.jeesite.modules.sys.entity.User" label="User"/>  
  48.         <dict value="com.thinkgem.jeesite.modules.sys.entity.Office" label="Office"/>  
  49.         <dict value="com.thinkgem.jeesite.modules.sys.entity.Area" label="Area"/>  
  50.         <dict value="This" label="ThisObj" description="生成當前對象"/>  
  51.         <dict value="Custom" label="Custom" description="自定義對象,生成後手動設置"/>  
  52.     </javaType>  
  53.     <!-- 查詢類型 -->  
  54.     <queryType>  
  55.         <dict value="=" label="="/>  
  56.         <dict value="!=" label="!="/>  
  57.         <dict value=">" label=">"/>  
  58.         <dict value=">=" label=">="/>  
  59.         <dict value="<" label="<"/>  
  60.         <dict value="<=" label="<="/>  
  61.         <dict value="between" label="Between"/>  
  62.         <dict value="like" label="Like"/>  
  63.         <dict value="left_like" label="Left Like"/>  
  64.         <dict value="right_like" label="Right Like"/>  
  65.     </queryType>  
  66.     <!-- 字段顯示類型 -->  
  67.     <showType>  
  68.         <dict value="input" label="單行文本"/>  
  69.         <dict value="textarea" label="多行文本"/>  
  70.         <dict value="select" label="下拉選項"/>  
  71.         <dict value="radiobox" label="單選按鈕"/>  
  72.         <dict value="checkbox" label="複選框"/>  
  73.         <dict value="dateselect" label="日期選擇"/>  
  74.         <dict value="userselect" label="人員選擇"/>  
  75.         <dict value="officeselect" label="部門選擇"/>  
  76.         <dict value="areaselect" label="區域選擇"/>  
  77.         <dict value="treeselect" label="樹選擇控件"/>  
  78.         <dict value="fileselect" label="文件上傳選擇"/>  
  79.     </showType>  
  80. </config>  


其中

 

 

[html] view plain copy

 

  1. <childTable>  
  2.     <template>category-ref:dao</template>  
  3. </childTable>  

 

定義了子表,初看jeesite的代碼生成,有個困惑的地方就是,一般通過FreeMarker進行代碼生成定義的模板都是ftl格式的,而這裏卻是xml,什麼鬼,難道這裏不是用FreeMarker進行生成的??我們先來看下xml文件中的內容就清楚了:

 

 

[html] view plain copy

 

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <template>  
  3.     <name>controller</name>  
  4.     <filePath>src/main/java/${packageName}/${moduleName}/web/${subModuleName}</filePath>  
  5.     <fileName>${ClassName}Controller.java</fileName>  
  6.     <content><![CDATA[ 
  7. /** 
  8.  * Copyright &copy; 2012-2016 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved. 
  9.  */ 
  10. package ${packageName}.${moduleName}.web<#if subModuleName != "">.${subModuleName}</#if>; 
  11.  
  12. import javax.servlet.http.HttpServletRequest; 
  13. import javax.servlet.http.HttpServletResponse; 
  14.  
  15. import org.apache.shiro.authz.annotation.RequiresPermissions; 
  16. import org.springframework.beans.factory.annotation.Autowired; 
  17. import org.springframework.stereotype.Controller; 
  18. import org.springframework.ui.Model; 
  19. import org.springframework.web.bind.annotation.ModelAttribute; 
  20. import org.springframework.web.bind.annotation.RequestMapping; 
  21. import org.springframework.web.bind.annotation.RequestParam; 
  22. import org.springframework.web.servlet.mvc.support.RedirectAttributes; 
  23.  
  24. import com.thinkgem.jeesite.common.config.Global; 
  25. import com.thinkgem.jeesite.common.persistence.Page; 
  26. import com.thinkgem.jeesite.common.web.BaseController; 
  27. import com.thinkgem.jeesite.common.utils.StringUtils; 
  28. import ${packageName}.${moduleName}.entity<#if subModuleName != "">.${subModuleName}</#if>.${ClassName}; 
  29. import ${packageName}.${moduleName}.service<#if subModuleName != "">.${subModuleName}</#if>.${ClassName}Service; 
  30.  
  31. /** 
  32.  * ${functionName}Controller 
  33.  * @author ${functionAuthor} 
  34.  * @version ${functionVersion} 
  35.  */ 
  36. @Controller 
  37. @RequestMapping(value = "${r"${adminPath}"}/${urlPrefix}") 
  38. public class ${ClassName}Controller extends BaseController { 
  39.  
  40.     @Autowired 
  41.     private ${ClassName}Service ${className}Service; 
  42.      
  43.     @ModelAttribute 
  44.     public ${ClassName} get(@RequestParam(required=false) String id) { 
  45.         ${ClassName} entity = null; 
  46.         if (StringUtils.isNotBlank(id)){ 
  47.             entity = ${className}Service.get(id); 
  48.         } 
  49.         if (entity == null){ 
  50.             entity = new ${ClassName}(); 
  51.         } 
  52.         return entity; 
  53.     } 
  54.      
  55.     @RequiresPermissions("${permissionPrefix}:view") 
  56.     @RequestMapping(value = {"list", ""}) 
  57.     public String list(${ClassName} ${className}, HttpServletRequest request, HttpServletResponse response, Model model) { 
  58.         Page<${ClassName}> page = ${className}Service.findPage(new Page<${ClassName}>(request, response), ${className});  
  59.         model.addAttribute("page", page); 
  60.         return "${lastPackageName}/${viewPrefix}List"; 
  61.     } 
  62.  
  63.     @RequiresPermissions("${permissionPrefix}:view") 
  64.     @RequestMapping(value = "form") 
  65.     public String form(${ClassName} ${className}, Model model) { 
  66.         model.addAttribute("${className}", ${className}); 
  67.         return "${lastPackageName}/${viewPrefix}Form"; 
  68.     } 
  69.  
  70.     @RequiresPermissions("${permissionPrefix}:edit") 
  71.     @RequestMapping(value = "save") 
  72.     public String save(${ClassName} ${className}, Model model, RedirectAttributes redirectAttributes) { 
  73.         if (!beanValidator(model, ${className})){ 
  74.             return form(${className}, model); 
  75.         } 
  76.         ${className}Service.save(${className}); 
  77.         addMessage(redirectAttributes, "保存${functionNameSimple}成功"); 
  78.         return "redirect:"+Global.getAdminPath()+"/${viewPrefix}/?repage"; 
  79.     } 
  80.      
  81.     @RequiresPermissions("${permissionPrefix}:edit") 
  82.     @RequestMapping(value = "delete") 
  83.     public String delete(${ClassName} ${className}, RedirectAttributes redirectAttributes) { 
  84.         ${className}Service.delete(${className}); 
  85.         addMessage(redirectAttributes, "刪除${functionNameSimple}成功"); 
  86.         return "redirect:"+Global.getAdminPath()+"/${viewPrefix}/?repage"; 
  87.     } 
  88.  
  89. }]]>  
  90.     </content>  
  91. </template>  


其中的xml格式爲:

 

 

[html] view plain copy

 

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

 

發現其中的奧祕沒,他把模板內容都放在了content標籤的CDATA[]區。而且config.xml有相對應的bean,用來實現xml轉對象:

 

 

[html] view plain copy

 

  1. /**  
  2.  * 生成方案Entity  
  3.  * @author ThinkGem  
  4.  * @version 2013-10-15  
  5.  */  
  6. @XmlRootElement(name="config")  
  7. public class GenConfig implements Serializable {  
  8.       
  9.     private static final long serialVersionUID = 1L;  
  10.     private List<GenCategory> categoryList;   // 代碼模板分類  
  11.     private List<Dict> javaTypeList;      // Java類型  
  12.     private List<Dict> queryTypeList;     // 查詢類型  
  13.     private List<Dict> showTypeList;      // 顯示類型  
  14.   
  15.     public GenConfig() {  
  16.         super();  
  17.     }  
  18.   
  19.     @XmlElementWrapper(name = "category")  
  20.     @XmlElement(name = "category")  
  21.     public List<GenCategory> getCategoryList() {  
  22.         return categoryList;  
  23.     }  
  24.   
  25.     public void setCategoryList(List<GenCategory> categoryList) {  
  26.         this.categoryList = categoryList;  
  27.     }  
  28.   
  29.     @XmlElementWrapper(name = "javaType")  
  30.     @XmlElement(name = "dict")  
  31.     public List<Dict> getJavaTypeList() {  
  32.         return javaTypeList;  
  33.     }  
  34.   
  35.     public void setJavaTypeList(List<Dict> javaTypeList) {  
  36.         this.javaTypeList = javaTypeList;  
  37.     }  
  38.   
  39.     @XmlElementWrapper(name = "queryType")  
  40.     @XmlElement(name = "dict")  
  41.     public List<Dict> getQueryTypeList() {  
  42.         return queryTypeList;  
  43.     }  
  44.   
  45.     public void setQueryTypeList(List<Dict> queryTypeList) {  
  46.         this.queryTypeList = queryTypeList;  
  47.     }  
  48.   
  49.     @XmlElementWrapper(name = "showType")  
  50.     @XmlElement(name = "dict")  
  51.     public List<Dict> getShowTypeList() {  
  52.         return showTypeList;  
  53.     }  
  54.   
  55.     public void setShowTypeList(List<Dict> showTypeList) {  
  56.         this.showTypeList = showTypeList;  
  57.     }  
  58.       
  59. }  


其中的

 

 

[html] view plain copy

 

  1. private List<GenCategory> categoryList;           // 代碼模板分類  
  2. private List<Dict> javaTypeList;      // Java類型  
  3. private List<Dict> queryTypeList;     // 查詢類型  
  4. private List<Dict> showTypeList;      // 顯示類型  


對應的就是xml中預先定義好的

 

 

[html] view plain copy

 

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <config>  
  3.     <!-- 生成分類 -->  
  4.     <category>  
  5.         <category value="curd" label="增刪改查(單表)">  
  6.             <template>curd/controller.xml</template>  
  7.             ....  
  8.         </category>  
  9.         <category value="curd_many" label="增刪改查(一對多)">  
  10.             <template>curd/controller.xml</template>  
  11.             ....  
  12.             <childTable>  
  13.                 <template>category-ref:dao</template>  
  14.             </childTable>  
  15.         </category>  
  16.         <category value="dao" label="僅持久層(dao/entity/mapper)">  
  17.             <template>dao/dao.xml</template>  
  18.             ....  
  19.         </category>  
  20.         <category value="treeTable" label="樹結構表(一體)">  
  21.             <template>treetable/controller.xml</template>  
  22.             ....  
  23.         </category>  
  24.         <category value="treeTableAndList" label="樹結構表(左樹右表)">  
  25.             <template>category-ref:dao</template>  
  26.         </category>  
  27.     </category>  
  28.     <!-- java類型 -->  
  29.     <javaType>  
  30.         <dict value="String" label="String"/>  
  31.         ....  
  32.     </javaType>  
  33.     <!-- 查詢類型 -->  
  34.     <queryType>  
  35.         <dict value="=" label="="/>  
  36.         ....  
  37.     </queryType>  
  38.     <!-- 字段顯示類型 -->  
  39.     <showType>  
  40.         <dict value="input" label="單行文本"/>  
  41.         <dict value="textarea" label="多行文本"/>  
  42.         ....  
  43.     </showType>  
  44. </config>  

 

其中的代碼模板分類

通過@XmlElement(name = "category")引用了GenCategory類,其中定義了主子模板

 

[html] view plain copy

 

  1. /**  
  2.  * 生成方案Entity  
  3.  * @author ThinkGem  
  4.  * @version 2013-10-15  
  5.  */  
  6. @XmlRootElement(name="category")  
  7. public class GenCategory extends Dict {  
  8.       
  9.     private static final long serialVersionUID = 1L;  
  10.     private List<String> template;            // 主表模板  
  11.     private List<String> childTableTemplate;// 子表模板  
  12.       
  13.     public static String CATEGORY_REF = "category-ref:";  
  14.   
  15.     public GenCategory() {  
  16.         super();  
  17.     }  
  18.   
  19.     @XmlElement(name = "template")  
  20.     public List<String> getTemplate() {  
  21.         return template;  
  22.     }  
  23.   
  24.     public void setTemplate(List<String> template) {  
  25.         this.template = template;  
  26.     }  
  27.       
  28.     @XmlElementWrapper(name = "childTable")  
  29.     @XmlElement(name = "template")  
  30.     public List<String> getChildTableTemplate() {  
  31.         return childTableTemplate;  
  32.     }  
  33.   
  34.     public void setChildTableTemplate(List<String> childTableTemplate) {  
  35.         this.childTableTemplate = childTableTemplate;  
  36.     }  
  37.       
  38. }  


這兩個主子其實對應的就是

 

 

在GenUtils中通過getConfig()方法可獲取轉換成bean的對象

 

 

而其中的數據就是在配置業務表是初始化的一些數據,比如當我們選擇某一張表時,然後點擊下一步

 

 

就會調用GenTableController中的form方法,把一些配置參數設置進去

 

然後在genTableForm.jsp頁面進行渲染

 

[html] view plain copy

 

  1. <%@ page contentType="text/html;charset=UTF-8" %>  
  2. <%@ include file="/WEB-INF/views/include/taglib.jsp"%>  
  3. <html>  
  4. <head>  
  5.     <title>業務表管理</title>  
  6.     <meta name="decorator" content="default"/>  
  7.     <script type="text/javascript">  
  8.         $(document).ready(function() {  
  9.             $("#comments").focus();  
  10.             $("#inputForm").validate({  
  11.                 submitHandler: function(form){  
  12.                     loading('正在提交,請稍等...');  
  13.                     $("input[type=checkbox]").each(function(){  
  14.                         $(this).after("<input type=\"hidden\" name=\""+$(this).attr("name")+"\" value=\""  
  15.                                 +($(this).attr("checked")?"1":"0")+"\"/>");  
  16.                         $(this).attr("name", "_"+$(this).attr("name"));  
  17.                     });  
  18.                     form.submit();  
  19.                 },  
  20.                 errorContainer: "#messageBox",  
  21.                 errorPlacement: function(error, element) {  
  22.                     $("#messageBox").text("輸入有誤,請先更正。");  
  23.                     if (element.is(":checkbox")||element.is(":radio")||element.parent().is(".input-append")){  
  24.                         error.appendTo(element.parent().parent());  
  25.                     } else {  
  26.                         error.insertAfter(element);  
  27.                     }  
  28.                 }  
  29.             });  
  30.         });  
  31.     </script>  
  32. </head>  
  33. <body>  
  34.     <ul class="nav nav-tabs">  
  35.         <li><a href="${ctx}/gen/genTable/">業務表列表</a></li>  
  36.         <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>  
  37.     </ul>  
  38.     <c:choose>  
  39.         <c:when test="${empty genTable.name}">  
  40.             <form:form id="inputForm" modelAttribute="genTable" action="${ctx}/gen/genTable/form" method="post" class="form-horizontal">  
  41.                 <form:hidden path="id"/>  
  42.                 <sys:message content="${message}"/>  
  43.                 <br/>  
  44.                 <div class="control-group">  
  45.                     <label class="control-label">表名:</label>  
  46.                     <div class="controls">  
  47.                         <form:select path="name" class="input-xxlarge">  
  48.                             <form:options items="${tableList}" itemLabel="nameAndComments" itemValue="name" htmlEscape="false"/>  
  49.                         </form:select>  
  50.                     </div>  
  51.                     <div class="form-actions">  
  52.                         <input id="btnSubmit" class="btn btn-primary" type="submit" value="下一步"/>   
  53.                         <input id="btnCancel" class="btn" type="button" value="返 回" οnclick="history.go(-1)"/>  
  54.                     </div>  
  55.                 </div>  
  56.             </form:form>  
  57.         </c:when>  
  58.         <c:otherwise>  
  59.             <form:form id="inputForm" modelAttribute="genTable" action="${ctx}/gen/genTable/save" method="post" class="form-horizontal">  
  60.                 <form:hidden path="id"/>  
  61.                 <sys:message content="${message}"/>  
  62.                 <fieldset>  
  63.                     <legend>基本信息</legend>  
  64.                     <div class="control-group">  
  65.                         <label class="control-label">表名:</label>  
  66.                         <div class="controls">  
  67.                             <form:input path="name" htmlEscape="false" maxlength="200" class="required" readonly="true"/>  
  68.                         </div>  
  69.                     </div>  
  70.                     <div class="control-group">  
  71.                         <label class="control-label">說明:</label>  
  72.                         <div class="controls">  
  73.                             <form:input path="comments" htmlEscape="false" maxlength="200" class="required"/>  
  74.                         </div>  
  75.                     </div>  
  76.                     <div class="control-group">  
  77.                         <label class="control-label">類名:</label>  
  78.                         <div class="controls">  
  79.                             <form:input path="className" htmlEscape="false" maxlength="200" class="required"/>  
  80.                         </div>  
  81.                     </div>  
  82.                     <div class="control-group">  
  83.                         <label class="control-label">父表表名:</label>  
  84.                         <div class="controls">  
  85.                             <form:select path="parentTable" cssClass="input-xlarge">  
  86.                                 <form:option value="">無</form:option>  
  87.                                 <form:options items="${tableList}" itemLabel="nameAndComments" itemValue="name" htmlEscape="false"/>  
  88.                             </form:select>  
  89.                              當前表外鍵:  
  90.                             <form:select path="parentTableFk" cssClass="input-xlarge">  
  91.                                 <form:option value="">無</form:option>  
  92.                                 <form:options items="${genTable.columnList}" itemLabel="nameAndComments" itemValue="name" htmlEscape="false"/>  
  93.                             </form:select>  
  94.                             <span class="help-inline">如果有父表,請指定父表表名和外鍵</span>  
  95.                         </div>  
  96.                     </div>  
  97.                     <div class="control-group hide">  
  98.                         <label class="control-label">備註:</label>  
  99.                         <div class="controls">  
  100.                             <form:textarea path="remarks" htmlEscape="false" rows="4" maxlength="200" class="input-xxlarge"/>  
  101.                         </div>  
  102.                     </div>  
  103.                     <legend>字段列表</legend>  
  104.                     <div class="control-group">  
  105.                         <table id="contentTable" class="table table-striped table-bordered table-condensed">  
  106.                             <thead><tr>  
  107.                                 <th title="數據庫字段名">列名</th>  
  108.                                 <th title="默認讀取數據庫字段備註">說明</th>  
  109.                                 <th title="數據庫中設置的字段類型及長度">物理類型</th>  
  110.                                 <th title="實體對象的屬性字段類型">Java類型</th>  
  111.                                 <th title="實體對象的屬性字段(對象名.屬性名|屬性名2|屬性名3,例如:用戶user.id|name|loginName,屬性名2和屬性名3爲Join時關聯查詢的字段)">Java屬性名稱 <i class="icon-question-sign"></i></th>  
  112.                                 <th title="是否是數據庫主鍵">主鍵</th><th title="字段是否可爲空值,不可爲空字段自動進行空值驗證">可空</th><th title="選中後該字段被加入到insert語句裏">插入</th>  
  113.                                 <th title="選中後該字段被加入到update語句裏">編輯</th><th title="選中後該字段被加入到查詢列表裏">列表</th>  
  114.                                 <th title="選中後該字段被加入到查詢條件裏">查詢</th><th title="該字段爲查詢字段時的查詢匹配放鬆">查詢匹配方式</th>  
  115.                                 <th title="字段在表單中顯示的類型">顯示錶單類型</th><th title="顯示錶單類型設置爲“下拉框、複選框、點選框”時,需設置字典的類型">字典類型</th><th>排序</th></tr></thead>  
  116.                             <tbody>  
  117.                             <c:forEach items="${genTable.columnList}" var="column" varStatus="vs">  
  118.                                 <tr${column.delFlag eq '1'?' class="error" title="已刪除的列,保存之後消失!"':''}>  
  119.                                     <td nowrap>  
  120.                                         <input type="hidden" name="columnList[${vs.index}].id" value="${column.id}"/>  
  121.                                         <input type="hidden" name="columnList[${vs.index}].delFlag" value="${column.delFlag}"/>  
  122.                                         <input type="hidden" name="columnList[${vs.index}].genTable.id" value="${column.genTable.id}"/>  
  123.                                         <input type="hidden" name="columnList[${vs.index}].name" value="${column.name}"/>${column.name}  
  124.                                     </td>  
  125.                                     <td>  
  126.                                         <input type="text" name="columnList[${vs.index}].comments" value="${column.comments}" maxlength="200" class="required" style="width:100px;"/>  
  127.                                     </td>  
  128.                                     <td nowrap>  
  129.                                         <input type="hidden" name="columnList[${vs.index}].jdbcType" value="${column.jdbcType}"/>${column.jdbcType}  
  130.                                     </td>  
  131.                                     <td>  
  132.                                         <select name="columnList[${vs.index}].javaType" class="required input-mini" style="width:85px;*width:75px">  
  133.                                             <c:forEach items="${config.javaTypeList}" var="dict">  
  134.                                                 <option value="${dict.value}" ${dict.value==column.javaType?'selected':''} title="${dict.description}">${dict.label}</option>  
  135.                                             </c:forEach>  
  136.                                         </select>  
  137.                                     </td>  
  138.                                     <td>  
  139.                                         <input type="text" name="columnList[${vs.index}].javaField" value="${column.javaField}" maxlength="200" class="required input-small"/>  
  140.                                     </td>  
  141.                                     <td>  
  142.                                         <input type="checkbox" name="columnList[${vs.index}].isPk" value="1" ${column.isPk eq '1' ? 'checked' : ''}/>  
  143.                                     </td>  
  144.                                     <td>  
  145.                                         <input type="checkbox" name="columnList[${vs.index}].isNull" value="1" ${column.isNull eq '1' ? 'checked' : ''}/>  
  146.                                     </td>  
  147.                                     <td>  
  148.                                         <input type="checkbox" name="columnList[${vs.index}].isInsert" value="1" ${column.isInsert eq '1' ? 'checked' : ''}/>  
  149.                                     </td>  
  150.                                     <td>  
  151.                                         <input type="checkbox" name="columnList[${vs.index}].isEdit" value="1" ${column.isEdit eq '1' ? 'checked' : ''}/>  
  152.                                     </td>  
  153.                                     <td>  
  154.                                         <input type="checkbox" name="columnList[${vs.index}].isList" value="1" ${column.isList eq '1' ? 'checked' : ''}/>  
  155.                                     </td>  
  156.                                     <td>  
  157.                                         <input type="checkbox" name="columnList[${vs.index}].isQuery" value="1" ${column.isQuery eq '1' ? 'checked' : ''}/>  
  158.                                     </td>  
  159.                                     <td>  
  160.                                         <select name="columnList[${vs.index}].queryType" class="required input-mini">  
  161.                                             <c:forEach items="${config.queryTypeList}" var="dict">  
  162.                                                 <option value="${fns:escapeHtml(dict.value)}" ${fns:escapeHtml(dict.value)==column.queryType?'selected':''} title="${dict.description}">${fns:escapeHtml(dict.label)}</option>  
  163.                                             </c:forEach>  
  164.                                         </select>  
  165.                                     </td>  
  166.                                     <td>  
  167.                                         <select name="columnList[${vs.index}].showType" class="required" style="width:100px;">  
  168.                                             <c:forEach items="${config.showTypeList}" var="dict">  
  169.                                                 <option value="${dict.value}" ${dict.value==column.showType?'selected':''} title="${dict.description}">${dict.label}</option>  
  170.                                             </c:forEach>  
  171.                                         </select>  
  172.                                     </td>  
  173.                                     <td>  
  174.                                         <input type="text" name="columnList[${vs.index}].dictType" value="${column.dictType}" maxlength="200" class="input-mini"/>  
  175.                                     </td>  
  176.                                     <td>  
  177.                                         <input type="text" name="columnList[${vs.index}].sort" value="${column.sort}" maxlength="200" class="required input-min digits"/>  
  178.                                     </td>  
  179.                                 </tr>  
  180.                             </c:forEach>  
  181.                             </tbody>  
  182.                         </table>  
  183.                     </div>  
  184.                 </fieldset>  
  185.                 <div class="form-actions">  
  186.                     <shiro:hasPermission name="gen:genTable:edit"><input id="btnSubmit" class="btn btn-primary" type="submit" value="保 存"/> </shiro:hasPermission>  
  187.                     <input id="btnCancel" class="btn" type="button" value="返 回" οnclick="history.go(-1)"/>  
  188.                 </div>  
  189.             </form:form>  
  190.         </c:otherwise>  
  191.     </c:choose>  
  192. </body>  
  193. </html>  


注意其中的name屬性

 

 

[html] view plain copy

 

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

 

在GenTable中是用list來裝的

 

所以在spring mvc數據綁定的時候可以通過下標的形式來傳值

 

 

業務表配置好之後,就是生成代碼,新建生成方案配置,然後輸入一些必須的信息

 

 

點擊保存並生成代碼,會調用GenSchemeController中的save()方法,傳入一些參數

 

 

然後調用genSchemeService.save()方法進行生成

 

 

如果是1的話就生成代碼

 

 

generateCode方法如下:

 

[html] view plain copy

 

  1. private String generateCode(GenScheme genScheme){  
  2.   
  3.     StringBuilder result = new StringBuilder();  
  4.       
  5.     // 查詢主表及字段列  
  6.     GenTable genTable = genTableDao.get(genScheme.getGenTable().getId());  
  7.     genTable.setColumnList(genTableColumnDao.findList(new GenTableColumn(new GenTable(genTable.getId()))));  
  8.       
  9.     // 獲取所有代碼模板  
  10.     GenConfig config = GenUtils.getConfig();  
  11.       
  12.     // 獲取模板列表  
  13.     List<GenTemplate> templateList = GenUtils.getTemplateList(config, genScheme.getCategory(), false); //獲取所有不包含childTableTemplateList的數據  
  14.     List<GenTemplate> childTableTemplateList = GenUtils.getTemplateList(config, genScheme.getCategory(), true);  
  15.       
  16.     // 如果有子表模板,則需要獲取子表列表  
  17.     if (childTableTemplateList.size() > 0){  
  18.         GenTable parentTable = new GenTable();  
  19.         parentTable.setParentTable(genTable.getName());  
  20.         genTable.setChildList(genTableDao.findList(parentTable));  
  21.     }  
  22.       
  23.     // 生成子表模板代碼  
  24.     for (GenTable childTable : genTable.getChildList()){  
  25.         childTable.setParent(genTable);  
  26.         childTable.setColumnList(genTableColumnDao.findList(new GenTableColumn(new GenTable(childTable.getId()))));  
  27.         genScheme.setGenTable(childTable);  
  28.         Map<String, Object> childTableModel = GenUtils.getDataModel(genScheme);  
  29.         for (GenTemplate tpl : childTableTemplateList){  
  30.             result.append(GenUtils.generateToFile(tpl, childTableModel, genScheme.getReplaceFile()));  
  31.         }  
  32.     }  
  33.       
  34.     // 生成主表模板代碼  
  35.     genScheme.setGenTable(genTable);  
  36.     Map<String, Object> model = GenUtils.getDataModel(genScheme);  
  37.     for (GenTemplate tpl : templateList){  
  38.         result.append(GenUtils.generateToFile(tpl, model, genScheme.getReplaceFile()));  
  39.     }  
  40.     return result.toString();  
  41. }  

 

該方法主要是做一些,獲取模板,然後進行數據綁定等一些工作。其中的

 

[html] view plain copy

 

  1. // 獲取模板列表  
  2. List<GenTemplate> templateList = GenUtils.getTemplateList(config, genScheme.getCategory(), false); //獲取所有不包含childTableTemplateList的數據  
  3. List<GenTemplate> childTableTemplateList = GenUtils.getTemplateList(config, genScheme.getCategory(), true);   

getTemplateList方法爲

 

[html] view plain copy

 

  1. /**  
  2.  * 根據分類獲取模板列表  
  3.  * @param config  
  4.  * @param category  
  5.  * @param isChildTable 是否是子表  
  6.  * @return  
  7.  */  
  8. public static List<GenTemplate> getTemplateList(GenConfig config, String category, boolean isChildTable){  
  9.     List<GenTemplate> templateList = Lists.newArrayList();  
  10.     if (config !=null && config.getCategoryList() != null && category !=  null){  
  11.         for (GenCategory e : config.getCategoryList()){  
  12.             if (category.equals(e.getValue())){  
  13.                 List<String> list = null;  
  14.                 if (!isChildTable){  
  15.                     list = e.getTemplate();  
  16.                 }else{  
  17.                     list = e.getChildTableTemplate();  
  18.                 }  
  19.                 if (list != null){  
  20.                     for (String s : list){  
  21.                         if (StringUtils.startsWith(s, GenCategory.CATEGORY_REF)){  
  22.                             templateList.addAll(getTemplateList(config, StringUtils.replace(s, GenCategory.CATEGORY_REF, ""), false));  
  23.                         }else{  
  24.                             GenTemplate template = fileToObject(s, GenTemplate.class);  
  25.                             if (template != null){  
  26.                                 templateList.add(template);  
  27.                             }  
  28.                         }  
  29.                     }  
  30.                 }  
  31.                 break;  
  32.             }  
  33.         }  
  34.     }  
  35.     return templateList;  
  36. }  


通過標誌位來獲取

 

[html] view plain copy

 

  1. if (!isChildTable){  
  2.     list = e.getTemplate();  
  3. }else{  
  4.     list = e.getChildTableTemplate();  
  5. }  

主表,子表模板,生成文件的方法是GenUtils.generateToFile(tpl, model, genScheme.getReplaceFile())

 

 

[html] view plain copy

 

  1. /**  
  2.  * 生成到文件  
  3.  * @param tpl  
  4.  * @param model  
  5.  * @param isReplaceFile  
  6.  * @return  
  7.  */  
  8. public static String generateToFile(GenTemplate tpl, Map<String, Object> model, boolean isReplaceFile){  
  9.     // 獲取生成文件  
  10.     String fileName = Global.getProjectPath() + File.separator   
  11.             + StringUtils.replaceEach(FreeMarkers.renderString(tpl.getFilePath() + "/", model),   
  12.                     new String[]{"//", "/", "."}, new String[]{File.separator, File.separator, File.separator})  
  13.             + FreeMarkers.renderString(tpl.getFileName(), model);  
  14.     logger.debug(" fileName === " + fileName);  
  15.   
  16.     // 獲取生成文件內容  
  17.     String content = FreeMarkers.renderString(StringUtils.trimToEmpty(tpl.getContent()), model);  
  18.     logger.debug(" content === \r\n" + content);  
  19.       
  20.     // 如果選擇替換文件,則刪除原文件  
  21.     if (isReplaceFile){  
  22.         FileUtils.deleteFile(fileName);  
  23.     }  
  24.       
  25.     // 創建並寫入文件  
  26.     if (FileUtils.createFile(fileName)){  
  27.         FileUtils.writeToFile(fileName, content, true);  
  28.         logger.debug(" file create === " + fileName);  
  29.         return "生成成功:"+fileName+"<br/>";  
  30.     }else{  
  31.         logger.debug(" file extents === " + fileName);  
  32.         return "文件已存在:"+fileName+"<br/>";  
  33.     }  
  34. }  


生成成功之後,會有如下提示:

 

發佈了31 篇原創文章 · 獲贊 110 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章