《开源框架那点事儿23》:采用TinyDB组件方式开发

采用TinyDB组件方式开发

步骤

Icon 前文介绍四则运算的流程编程开发时,说过流程编排在开发重复功能时,可以利用已有的组件库快速开发。对于开发人员而言只需要简单配置流程就可以完成工作了。
开发增删改查的组件接口。本来这部分很花费时间,如果采用组件复用的话,就可以实现一次开发,终生受益。

  • 配置curd.beans.xml和tinydb.xml。
  • 使用流程编辑器定制组件流程curd.pageflow。
  • 修改页面文件:list.page和operate.page,使之符合流程方式调用。
  • 修改布局文件default.layout。

    完整的子工程目录如下:
    <ignore_js_op>


首先是开发增删改查的组件接口,如果是开发人员自己实现的话就是实现ComponentInterface接口,然后在组件里实现具体的数据库逻辑,其实Tiny框架提供基础组件库,配合TinyDB进行开发,可以实现无Pojo,无Dao层,在本示例中开发人员不用写一行Java代码,通过配置就可以完成示例需求。

基础组件资源

Icon目前Tiny框架提供如下几种组件库,用户可以根据实际需要配合流程编辑器使用。

  • org.tinygroup.flowbasiccomponent 提供了逻辑基本组件,如对象转换组件、调用静态方法和bean组件等。
  • org.tinygroup.flowservicecomponent 提供了逻辑基本服务,如调用服务、调用本地流程、调用页面流程等。
  • org.tinygroup.tinydbflowcomponent 提供了TinyDB数据库组件,如插入组件、更新组件、删除组件、查询记录组件等。
  • org.tinygroup.pageflowbasiccomponent 提供了页面基本组件,如页面重定向、页面转发等。

    开发人员想要使用使用组件库中的内置组件,必须将具体的依赖加入到工程的pom.xml,这样在使用图形化工具,在右侧的组件列表就能看到组件清单:
    <ignore_js_op>
     


本示例用到了数据库访问和页面跳转,pom.xml里面需要有如下依赖:

<dependency>
<groupId>org.tinygroup</groupId>
<artifactId>org.tinygroup.tinydbflowcomponent</artifactId>
<version>${tiny_version}</version>
</dependency>
<dependency>
<groupId>org.tinygroup</groupId>
<artifactId>org.tinygroup.pageflowbasiccomponent</artifactId>
<version>${tiny_version}</version>
< /dependency>


配置crud.beans.xml可以复用先前TinyDB采用服务方式的配置文件,只需要把如下内容删除:

<bean id="tinyDbCrudService" class="org.tinygroup.crud.service.impl.TinyDbCrudService" scope="singleton">
<property name="beanType" value="TUser" />
< /bean>



因为本示例并没有配置tinyDbCrudService,如果不删除的话,Web应用启动时会报异常。至于tinydb.xml文件无需任何修改,可以直接复用先前例子。

接下来按“New”-“Other”-“Tiny框架”-“页面流程”顺序,创建crud.pageflow,然后按下图拖曳组件:
<ignore_js_op>


接下来修改组件的基本信息:标识、英文名和中文名。以插入组件为例,鼠标选中画板里的“插入组件”,在Eclipse的下方的“Properties”,就可以看到如下内容:

<ignore_js_op>

 


五个组件修改完毕,界面如下图展示:

<ignore_js_op>

 



然后是配置组件的扩展属性,每个组件的扩展属性是根据自身功能定制的,具体的组件参数请参考各组件的帮助文档。这里还是以“新增用户”为例:

<ignore_js_op>

 


说明:这里类型就是数据库表的值对象类型TUser,模式是指数据库的schema,其他几个组件也是类似。

配置好五个组件的扩展属性,就是配置页面组件的扩展属性。页面组件的扩展属性就一个:页面路径。

页面重定向的配置如下:

<ignore_js_op>

 



查询单用户对应的页面转发配置如下:

<ignore_js_op>

 


查询用户列表对应的页面转发配置如下:

<ignore_js_op>

 


完整的curd.pageflow的内容如下:

  1. <flowid="crud"enable="true"private-context="false">
  2. <parameters/>
  3. <nodes>
  4. <nodeid="start"name="start"title="开始">
  5. <next-nodes>
  6. <next-nodenext-node-id="addUser"/>
  7. <next-nodenext-node-id="updateUser"/>
  8. <next-nodenext-node-id="deleteUserById"/>
  9. <next-nodenext-node-id="getUserById"/>
  10. <next-nodenext-node-id="redirectComponent"/>
  11. <next-nodenext-node-id="queryUsers"/>
  12. </next-nodes>
  13. </node>
  14. <nodeid="addUser"name="addUser"title="新增用户">
  15. <componentname="tinydbAddService"title="插入组件">
  16. <properties>
  17. <flow-propertyname="beanType"value="TUser"/>
  18. <flow-propertyname="schema"value="sample"/>
  19. </properties>
  20. </component>
  21. <next-nodes>
  22. <next-nodenext-node-id="redirectComponent"/>
  23. </next-nodes>
  24. </node>
  25. <nodeid="updateUser"name="updateUser"title="更新用户">
  26. <componentname="tinydbUpdateService"title="更新组件">
  27. <properties>
  28. <flow-propertyname="beanType"value="TUser"/>
  29. <flow-propertyname="schema"value="sample"/>
  30. </properties>
  31. </component>
  32. <next-nodes>
  33. <next-nodenext-node-id="redirectComponent"/>
  34. </next-nodes>
  35. </node>
  36. <nodeid="deleteUserById"name="deleteUserById"title="删除用户">
  37. <componentname="tinydbDeleteService"title="删除组件">
  38. <properties>
  39. <flow-propertyname="beanType"value="TUser"/>
  40. <flow-propertyname="schema"value="sample"/>
  41. </properties>
  42. </component>
  43. <next-nodes>
  44. <next-nodenext-node-id="redirectComponent"/>
  45. </next-nodes>
  46. </node>
  47. <nodeid="getUserById"name="getUserById"title="查询单用户">
  48. <componentname="tinydbQueryServiceWithId"title="单记录查询组件">
  49. <properties>
  50. <flow-propertyname="beanType"value="TUser"/>
  51. <flow-propertyname="schema"value="sample"/>
  52. <flow-propertyname="primaryKey"value="${primaryKey}"/>
  53. <flow-propertyname="resultKey"value="user"/>
  54. </properties>
  55. </component>
  56. <next-nodes>
  57. <next-nodenext-node-id="forwardComponent"/>
  58. </next-nodes>
  59. </node>
  60. <nodeid="forwardComponent"name="forwardComponent"title="页面转发">
  61. <componentname="forwardComponent"title="页面转发">
  62. <properties>
  63. <flow-propertyname="path"value="/crud/operate.page"/>
  64. </properties>
  65. </component>
  66. <next-nodes>
  67. <next-nodenext-node-id="end"/>
  68. </next-nodes>
  69. </node>
  70. <nodeid="redirectComponent"name="redirectComponent"title="页面重定向">
  71. <componentname="redirectComponent"title="页面重定向">
  72. <properties>
  73. <flow-propertyname="path"value="crud.pageflow?tiny_flow_id=queryUsers"/>
  74. </properties>
  75. </component>
  76. <next-nodes>
  77. <next-nodenext-node-id="end"/>
  78. </next-nodes>
  79. </node>
  80. <nodeid="queryUsers"name="queryUsers"title="查询用户列表">
  81. <componentname="tinydbQueryService"title="查询组件">
  82. <properties>
  83. <flow-propertyname="beanType"value="TUser"/>
  84. <flow-propertyname="schema"value="sample"/>
  85. <flow-propertyname="resultKey"value="users"/>
  86. </properties>
  87. </component>
  88. <next-nodes>
  89. <next-nodenext-node-id="forwardComponent_1"/>
  90. </next-nodes>
  91. </node>
  92. <nodeid="forwardComponent_1"name="forwardComponent"title="页面转发">
  93. <componentname="forwardComponent"title="页面转发">
  94. <properties>
  95. <flow-propertyname="path"value="/crud/list.page"/>
  96. </properties>
  97. </component>
  98. <next-nodes>
  99. <next-nodenext-node-id="end"/>
  100. </next-nodes>
  101. </node>
  102. <nodeid="end"name="end"title="结束">
  103. <next-nodes/>
  104. </node>
  105. </nodes>
  106. < /flow>
<flow id="crud" enable="true" private-context="false">
  <parameters/>
  <nodes>
    <node id="start" name="start" title="开始">
      <next-nodes>
        <next-node next-node-id="addUser"/>
        <next-node next-node-id="updateUser"/>
        <next-node next-node-id="deleteUserById"/>
        <next-node next-node-id="getUserById"/>
        <next-node next-node-id="redirectComponent"/>
        <next-node next-node-id="queryUsers"/>
      </next-nodes>
    </node>
    <node id="addUser" name="addUser" title="新增用户">
      <component name="tinydbAddService" title="插入组件">
        <properties>
          <flow-property name="beanType" value="TUser"/>
          <flow-property name="schema" value="sample"/>
        </properties>
      </component>
      <next-nodes>
        <next-node next-node-id="redirectComponent"/>
      </next-nodes>
    </node>
    <node id="updateUser" name="updateUser" title="更新用户">
      <component name="tinydbUpdateService" title="更新组件">
        <properties>
          <flow-property name="beanType" value="TUser"/>
          <flow-property name="schema" value="sample"/>
        </properties>
      </component>
      <next-nodes>
        <next-node next-node-id="redirectComponent"/>
      </next-nodes>
    </node>
    <node id="deleteUserById" name="deleteUserById" title="删除用户">
      <component name="tinydbDeleteService" title="删除组件">
        <properties>
          <flow-property name="beanType" value="TUser"/>
          <flow-property name="schema" value="sample"/>
        </properties>
      </component>
      <next-nodes>
        <next-node next-node-id="redirectComponent"/>
      </next-nodes>
    </node>
    <node id="getUserById" name="getUserById" title="查询单用户">
      <component name="tinydbQueryServiceWithId" title="单记录查询组件">
        <properties>
          <flow-property name="beanType" value="TUser"/>
          <flow-property name="schema" value="sample"/>
          <flow-property name="primaryKey" value="${primaryKey}"/>
          <flow-property name="resultKey" value="user"/>
        </properties>
      </component>
      <next-nodes>
        <next-node next-node-id="forwardComponent"/>
      </next-nodes>
    </node>
    <node id="forwardComponent" name="forwardComponent" title="页面转发">
      <component name="forwardComponent" title="页面转发">
        <properties>
          <flow-property name="path" value="/crud/operate.page"/>
        </properties>
      </component>
      <next-nodes>
        <next-node next-node-id="end"/>
      </next-nodes>
    </node>
    <node id="redirectComponent" name="redirectComponent" title="页面重定向">
      <component name="redirectComponent" title="页面重定向">
        <properties>
          <flow-property name="path" value="crud.pageflow?tiny_flow_id=queryUsers"/>
        </properties>
      </component>
      <next-nodes>
        <next-node next-node-id="end"/>
      </next-nodes>
    </node>
    <node id="queryUsers" name="queryUsers" title="查询用户列表">
      <component name="tinydbQueryService" title="查询组件">
        <properties>
          <flow-property name="beanType" value="TUser"/>
          <flow-property name="schema" value="sample"/>
          <flow-property name="resultKey" value="users"/>
        </properties>
      </component>
      <next-nodes>
        <next-node next-node-id="forwardComponent_1"/>
      </next-nodes>
    </node>
    <node id="forwardComponent_1" name="forwardComponent" title="页面转发">
      <component name="forwardComponent" title="页面转发">
        <properties>
          <flow-property name="path" value="/crud/list.page"/>
        </properties>
      </component>
      <next-nodes>
        <next-node next-node-id="end"/>
      </next-nodes>
    </node>
    <node id="end" name="end" title="结束">
      <next-nodes/>
    </node>
  </nodes>
< /flow>


操作页面operate.page代码如下:

  1. <formaction="${TINY_CONTEXT_PATH}/crud.pageflow">
  2. 姓名:<inputtype="text"name="name"value="${user?.name}"/><br/>
  3. 年龄:<inputtype="text"name="age"value="${user?.age}"/><br/>
  4. <inputtype="hidden"name="id"value="${user?.id}"/>
  5. #if($user)
  6. <inputtype="hidden"name="tiny_flow_id"value="updateUser"/>
  7. #else
  8. <inputtype="hidden"name="tiny_flow_id"value="addUser"/>
  9. #end
  10. <inputtype="submit"value="提交">
  11. < /form>
<form action="${TINY_CONTEXT_PATH}/crud.pageflow">
姓名:<input type="text" name="name" value="${user?.name}" /><br/>
年龄:<input type="text" name="age" value="${user?.age}" /><br/>
 <input type="hidden" name="id" value="${user?.id}"/>
 #if($user)
 <input type="hidden" name="tiny_flow_id" value="updateUser"/>
 #else
 <input type="hidden" name="tiny_flow_id" value="addUser"/>
 #end
< input type="submit" value="提交">
< /form>


列表页面list.page代码如下:

  1. 用户管理界面:
  2. <form>
  3. <div>
  4. <p>
  5. <inputtype="button"id="add"value="添加"/>
  6. <inputtype="button"id="update"value="修改"/>
  7. <inputtype="button"id="delete"value="删除"/>
  8. </p>
  9. <tablecellpadding="0"cellspacing="1"border="0"bgcolor="#ebebeb"width="500px">
  10. <tbody>
  11. <trbgcolor="#ffffff">
  12. <thwidth="35"><inputtype="checkbox"id="selectAll"/></th>
  13. <thwidth="100px"height="35">名称</th>
  14. <thwidth="365px">年龄</th>
  15. </tr>
  16. #foreach($user in $users)
  17. <trbgcolor="#ffffff">
  18. <tdalign="center"><inputtype="checkbox"name="id"value="$user.id"/></td>
  19. <tdalign="center"height="30">$user.name</td>
  20. <tdalign="center">$user.age</td>
  21. </tr>
  22. #end
  23. </tbody>
  24. </table>
  25. < /div>
  26. <form>
  27. <script>
  28. $(document).ready(function(){
  29. $("#selectAll").click(function(){
  30. var checked=$(this).get(0).checked;
  31. $(":checkbox:not('#selectAll')").each(function(){
  32. $(this).get(0).checked=checked;
  33. });
  34. });
  35. $("#add").click(function(){
  36. location.href="${TINY_CONTEXT_PATH}/crud/operate.page";
  37. }
  38. );
  39. $("#update").click(function(){
  40. var checkboxs=$(":checked:not('#selectAll')");
  41. var size=checkboxs.size();
  42. if(size==0){
  43. alert("修改前请先选择记录");
  44. }else if(size>1){
  45. alert("只能选择一条记录进行修改");
  46. }else{
  47. var checkbox=checkboxs.get(0);
  48. location.href="${TINY_CONTEXT_PATH}/crud.pageflow?primaryKey="+checkbox.value+"&tiny_flow_id=getUserById";
  49. }
  50. }
  51. );
  52. $("#delete").click(function(){
  53. if(confirm("确定要删除选择的记录吗?")){
  54. var checkboxs=$(":checked:not('#selectAll')");
  55. var size=checkboxs.size();
  56. if(size==0){
  57. alert("删除前请先选择记录");
  58. }else if(size>1){
  59. alert("只能选择一条记录进行删除");
  60. }else{
  61. var checkbox=checkboxs.get(0);
  62. location.href="${TINY_CONTEXT_PATH}/crud.pageflow?id="+checkbox.value+"&tiny_flow_id=deleteUserById";
  63. }
  64. }
  65. }
  66. );
  67. });
  68. < /script>
用户管理界面:
<form>
< div>
 <p>
  <input type="button" id="add" value="添加"/>
     <input type="button" id="update" value="修改"/>
     <input type="button" id="delete" value="删除"/>
 </p>
 <table cellpadding="0" cellspacing="1" border="0" bgcolor="#ebebeb" width="500px">
  <tbody>
   <tr bgcolor="#ffffff">
    <th width="35"><input type="checkbox" id="selectAll"/></th>
    <th width="100px" height="35">名称</th>
    <th width="365px" >年龄</th>
   </tr>
   #foreach($user in $users)
   <tr bgcolor="#ffffff">
    <td align="center"><input type="checkbox" name="id" value="$user.id"/></td>
    <td align="center" height="30">$user.name</td>
    <td align="center">$user.age</td>
   </tr>
   #end
  </tbody>
 </table>
< /div>
< form>
< script>
$(document).ready(function(){
   $("#selectAll").click(function(){
        var checked=$(this).get(0).checked;
        $(":checkbox:not('#selectAll')").each(function(){
               $(this).get(0).checked=checked;
        });
     });
   $("#add").click(function(){
       location.href="${TINY_CONTEXT_PATH}/crud/operate.page";
    }
   );
   $("#update").click(function(){
    var checkboxs=$(":checked:not('#selectAll')");
    var size=checkboxs.size();
        if(size==0){
           alert("修改前请先选择记录");
        }else if(size>1){
           alert("只能选择一条记录进行修改");
        }else{
         var checkbox=checkboxs.get(0);
         location.href="${TINY_CONTEXT_PATH}/crud.pageflow?primaryKey="+checkbox.value+"&tiny_flow_id=getUserById";
        } 
    }
   );
    $("#delete").click(function(){
        if(confirm("确定要删除选择的记录吗?")){
              var checkboxs=$(":checked:not('#selectAll')");
               var size=checkboxs.size();
               if(size==0){
                alert("删除前请先选择记录");
               }else if(size>1){
                 alert("只能选择一条记录进行删除");
               }else{
              var checkbox=checkboxs.get(0);
             location.href="${TINY_CONTEXT_PATH}/crud.pageflow?id="+checkbox.value+"&tiny_flow_id=deleteUserById";
             }
        }
    }
   );
});
< /script>



默认布局文件default.layout的配置如下:

  1. <tableborder="1"width="100%">
  2. <tr>
  3. <tdcolspan="2">
  4. <ahref="${TINY_CONTEXT_PATH}/crud.pageflow?tiny_flow_id=queryUsers">用户管理</a><br/>
  5. </td>
  6. </tr>
  7. <tr>
  8. <tdwidth="20%">tinydb流程方式</td>
  9. <td>
  10. ${pageContent}
  11. </td>
  12. </tr>
  13. < /table>
<table border="1" width="100%">
   <tr>
      <td colspan="2">
        <a href="${TINY_CONTEXT_PATH}/crud.pageflow?tiny_flow_id=queryUsers">用户管理</a><br/>
      </td>
    </tr>
    <tr>  
      <td width="20%">tinydb流程方式</td>
      <td>
         ${pageContent}
      </td>
   </tr>
< /table>



到这一步,流程编排的例子算是开发完毕。
演示效果<ignore_js_op>


具体的增删改查效果,用户可以根据教程自行尝试。


欢迎访问开源技术社区:http://bbs.tinygroup.org。本例涉及的代码和框架资料,将会在社区分享。《自己动手写框架》QQ成员群:228977971,一起动手,了解开源框架的奥秘!或点击加入群:http://jq.qq.com/?_wv=1027&k=d0myfX

猜你喜欢

转载自j2eetop.iteye.com/blog/2227028
今日推荐