1. 程式人生 > >jeesite快速開發平臺(七)----程式碼生成原理

jeesite快速開發平臺(七)----程式碼生成原理

一、原理講解


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




一看就知道crud就是基本的增刪改查,dao是資料庫操作,treetable是有關樹方面的模板,其中主要的配置檔案就是config.xml,該檔案中定義了生成的模板,以及java型別,查詢型別,欄位顯示型別等一些資料。


   
  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>

其中


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

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


   
  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. import javax.servlet.http.HttpServletRequest;
  12. import javax.servlet.http.HttpServletResponse;
  13. import org.apache.shiro.authz.annotation.RequiresPermissions;
  14. import org.springframework.beans.factory.annotation.Autowired;
  15. import org.springframework.stereotype.Controller;
  16. import org.springframework.ui.Model;
  17. import org.springframework.web.bind.annotation.ModelAttribute;
  18. import org.springframework.web.bind.annotation.RequestMapping;
  19. import org.springframework.web.bind.annotation.RequestParam;
  20. import org.springframework.web.servlet.mvc.support.RedirectAttributes;
  21. import com.thinkgem.jeesite.common.config.Global;
  22. import com.thinkgem.jeesite.common.persistence.Page;
  23. import com.thinkgem.jeesite.common.web.BaseController;
  24. import com.thinkgem.jeesite.common.utils.StringUtils;
  25. import ${packageName}.${moduleName}.entity<#if subModuleName != "">.${subModuleName}</#if>.${ClassName};
  26. import ${packageName}.${moduleName}.service<#if subModuleName != "">.${subModuleName}</#if>.${ClassName}Service;
  27. /**
  28. * ${functionName}Controller
  29. * @author ${functionAuthor}
  30. * @version ${functionVersion}
  31. */
  32. @Controller
  33. @RequestMapping(value = "${r"${adminPath}"}/${urlPrefix}")
  34. public class ${ClassName}Controller extends BaseController {
  35. @Autowired
  36. private ${ClassName}Service ${className}Service;
  37. @ModelAttribute
  38. public ${ClassName} get(@RequestParam(required=false) String id) {
  39. ${ClassName} entity = null;
  40. if (StringUtils.isNotBlank(id)){
  41. entity = ${className}Service.get(id);
  42. }
  43. if (entity == null){
  44. entity = new ${ClassName}();
  45. }
  46. return entity;
  47. }
  48. @RequiresPermissions("${permissionPrefix}:view")
  49. @RequestMapping(value = {"list", ""})
  50. public String list(${ClassName} ${className}, HttpServletRequest request, HttpServletResponse response, Model model) {
  51. Page<${ClassName}> page = ${className}Service.findPage(new Page<${ClassName}>(request, response), ${className});
  52. model.addAttribute("page", page);
  53. return "${lastPackageName}/${viewPrefix}List";
  54. }
  55. @RequiresPermissions("${permissionPrefix}:view")
  56. @RequestMapping(value = "form")
  57. public String form(${ClassName} ${className}, Model model) {
  58. model.addAttribute("${className}", ${className});
  59. return "${lastPackageName}/${viewPrefix}Form";
  60. }
  61. @RequiresPermissions("${permissionPrefix}:edit")
  62. @RequestMapping(value = "save")
  63. public String save(${ClassName} ${className}, Model model, RedirectAttributes redirectAttributes) {
  64. if (!beanValidator(model, ${className})){
  65. return form(${className}, model);
  66. }
  67. ${className}Service.save(${className});
  68. addMessage(redirectAttributes, "儲存${functionNameSimple}成功");
  69. return "redirect:"+Global.getAdminPath()+"/${viewPrefix}/?repage";
  70. }
  71. @RequiresPermissions("${permissionPrefix}:edit")
  72. @RequestMapping(value = "delete")
  73. public String delete(${ClassName} ${className}, RedirectAttributes redirectAttributes) {
  74. ${className}Service.delete(${className});
  75. addMessage(redirectAttributes, "刪除${functionNameSimple}成功");
  76. return "redirect:"+Global.getAdminPath()+"/${viewPrefix}/?repage";
  77. }
  78. }]]>
  79. </content>
  80. </template>

其中的xml格式為:


   
  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轉物件:



   
  1. /**