首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

转:传智播客-Jbpm(3)

2012-10-14 
转:传智播客--Jbpm(三)JBPM学习: ItcastOA使用技术:View + Servie(service + DAO)Struts1 + jstl1.1 + hib

转:传智播客--Jbpm(三)
JBPM学习: ItcastOA

使用技术:
    View + Servie(service + DAO)
    Struts1 + jstl1.1 + hibernate + jbpm

完成的功能:  
    组织与人员管理;
    流程管理:部署,删除,查看流程图片,备份
    流程监控:用图形显示当前正在执行的节点


----------------------------------------
组织与人员管理: 部门-》职务 -》人员

1. 环境准备:
    (1) Web App ;
        working set的使用:可以将工程分类,显示当前使用的工程;
    (2) 结构划分:
        src :
            src/java:       java源码;
            src/process:    流程定义;
            src/config:     配置文件;
            src/test:       测试用例,代码;
         doc:

    (3) 导入jar包:
        lib:
            jbpm(它含有Hibernate);
            struts(课堂使用MyEclipse自带的包);
            jstl(MyEclipse自带);
            数据库驱动(MySQL,总忘);

            ** jar包冲突的解决:
                -- 写测试代码:
                    -- Action:  src/test/ cn.itcast.oa.web.struts.actions.TestAction
                        syso:
                    -- FormBean: src/test/ cn.itcast.oa.web.struts.forms.TestForm
                        name
                    -- 配置及测试
                        课堂测试,没有冲突,可能jbpm自带的Hibernate的jar包与Struts没有冲突;
                        注意有这个问题;
                        beanutils, colloctions;
              
    (4) 配置文件:
            jbpm(带了Hibernate) -- src / config / 4个文件;
            struts              -- WEB-INF / struts-config.xml


2. 部门管理中需要的实体:
    思考:部门, 职务,人员

        职务与人员: 多对多;
      
        部门与人员: 一对多;

    部门:   id : Integer; name: String; 
            parent:Department;  children : Set<Department>; users : Set<User>;
    职务:  id : Integer; name: String; 
            users : Set<User>(可以取舍);
    人员:  id : Integer; name: String;   password:String; Email:String;
            department : Department; roles : Set<Role>;
       
    (1) 写实体类;
    (2) 写映射文件;
    (3) 分析部门列表的有关流程,功能;
        列出所有部门;增加、删除、修改部门;
    (4) 根据上述分析写出DepartmentAction的框架;
            list();
            saveUI(), save() -- addUI/updateUI(), add/update();
            del();
    (5) 这里将Service和DAO合成一层:Service;
        使用Hibernate,需要它的Session;
        所以将session统一管理,解决的方案就是继承
        将所有的Service抽象成一个基类:BaseService;
        它提供的一个方法就是getSession();
          
        写法处理:先写出方法,方法体的内容就是抛出一个UnsurpportedException;
        这样其他的Service可以写自己的代码;待最后写getSession();

     (7) findDepts的处理注意:
            对于顶层的部门,它的Parent=null;查询语句不要使用参数,
            而是直接指定parent=null;只有当parent!=null时才使用指定
            参数的方法获取部门列表;
      
     (8) 分析父类的session问题;
        itcastbbs: 每个请求一个事务;一个session;
        jbpm: jbpmContext内置一个session;

        为了保证它们在一个事物中,必须保证上述2个session是同一个;

来源:(http://blog.sina.com.cn/s/blog_5ecfe46a0100do23.html) - 传智播客--Jbpm(三)_hhl_bj_新浪博客
      (9) 写过滤器:cn.itcast.oa.web.filters.CloseSessionFilter implements Filter
      
            JbpmConfiguration.createJbpmContext();  // 将JbpmConfiguration对象作为成员变量;
                                                    // 再将它作为工具类;

            JbpmContext jbpmContext = null;

            doFilter();

            jbpmContext.close();

       (10) 写工具类:cn.itcast.oa.utils.JbpmContextManager :
             -- 将jbpmContextManager写成单例模式;
             -- // 获取当前线程的jbpmContext;
                // 如果没有就创建一个
                getCurrentJbpmContext() {
                     jbpmContext = jbpmConfiguration.getCurrentJbpmContext();
                     if (jbpmContext == null ) {
                            jbpmContext = jbpmConfiguration.createJbpmContext();
                     }
                }

                getCurrentJbpmContext(boolean create) {
                     jbpmContext = jbpmConfiguration.getCurrentJbpmContext();
                     if (jbpmContext == null && create) {
                            jbpmContext = jbpmConfiguration.createJbpmContext();
                     }

                     return jbpmContext;
                }


         (11) 基类Service
                jbpmContextManager.getInstance().getCurrentJbpmContext(true).getSession();
            
              过滤器中的
                jbpmContextManager.getInstance().getCurrentJbpmContext(false);
                if ( jbpmContext != null ) jbpmContext.close();

          (12) 关于事务控制的分析:** 如何理解整个的程序的思路
                要将这里的处理方法抽取出来,直接使用;

                1, Service层要与数据库交互,就必须获取Hibernate中的session;
                    多个Service都需要session,于是将getSession()方法抽取到父类中去;
                2, 本案例要使用jbpm;而jbpm与数据库交互也是用Hibernate,且它的API
                    中有JbpmContext来操作数据库;这个JbpmContext里面有一个session;
                3, 为了使每一次与数据库的交互【可能是jbpm,可能是Hibernate】都在同一个事务中,
                    就必须保证每次操作的session是同一个;                  
                4, 为了实现3的需求,我们做了一个单例的工具类;
                    这个工具类的目的就是获取当前的jbpmContext(这样,Service的父类可以
                    通过它获取session);
                    获取当前的jbpmContext时,如果已经有了一个jbpmContext,就直接使用,
                    没有的话就创建一个(如果传过来的参数要求创建的话);
                5, Filter在拦截的时候,在执行请求前,无需打开事务,jbpmContext会自动打开,
                    只需要在执行完请求后,关闭jbpmContext(jbpmContext.close())即可,jbpmContext
                    会自动关闭事务(需要查看文档证实);出现异常则回滚;
                    注意:并非每次请求都会使用session,所以这里获取jbpmContext时选择不创建,这
                    也是课堂上在工具类的getCurrentJbpmContext()方法中增加一个参数的作用;
                    这里就是不创建jbpmContext的情况(参数为false);
               
                (13) 乱码:Filter里面
              
                (14) saveOrUpdate()

                (15) 使用树形显示部门列表;
                    Department dept = null;
                    void printDept(Department dept) {
                        if (dept != null ) {
                            System.out.println(dept.getName());
                            for (Department child : dept.getChildren()) {
                                printDept(child);
                            }
                        }
                    }

                    void printDepts(Set<Department> depts) {
                        for (Department dept : depts) {
                            System.out.println(dept.getName());
                            printDepts(dept.getChildren());
                        }
                    }

                (16) 使用js和jsp写出部门列表;** Java与js的结合使用,数据交互;
                        写java方法生成字符串,放在js中;
                     写一个工具类:WebTreeUtil
                        public static String addXTreeItems(String tree, Department dept) {
                          
                        }

                        main(){
                             depts;
                             for (depts)
                                String code += addXTreeItems("tree", dept);
                             syso: code;
                        }
                  
                    (17) 如何选择部门?
                            使用js弹出一个窗口,该窗口显示部门列表
                                tree.add(new WebFXTreeItem("", "javascript:selDept(deptId, deptName);"));
                            js代码:
                                selDept(deptId, deptName);
                            java的工具类修改

                    (18) 跨域访问的问题:
                        html文件是本地的,打开正在运行的服务器的网页时出现问题;

                        本地访问本地;
                        服务器访问服务器;
                        本地访问服务器;
                        服务器访问本地;

热点排行