转:传智播客—jbpm与OA项目(三)

系统 1726 0

今日开始进行 OA 项目了, OA 是一个大型的办公自动化管理系统。汤老师使用 6 天的时间带领我们做这个项目,显然是不可能全部完成的,我们要做其中重点的几个模块。这个项目将对我们之前学习的 struts1 hibernate3 jbpm3 jstl1.1 junit4 进行综合性的系统练习。

 

在跟着老师学习新技术时,课堂上我们能很好的理解各知识点。但放到一起,在实际项目中应用时还时感觉有点陌生。不过还好,以前的工作经验和每天整理学习日志让这个项目的开端并未对我构成多大挑战。但这对一个新人来说,是需要反复揣摩的,也正是这种实践性的练习才让我们掌握和混用理论性的知识。

 

做为一个应用级别的开发人员不仅要熟练掌握编程技术,而且也要对各业务流程有一定的了解。这在日后的开发工作中将起到重要的作用。说的直白些,就是熟练、稳健的使用编程技术将业务流程搭建起来。所以在这种实践性项目中,我不仅要摸清各项技术的应用,也要熟悉业务流程,更要学好项目的架构。但是这个项目多少有些让我失望,因为它的重点是让同学们将之前学习的知识做个综合练习,所以没有从详细的需求分析、编程文档 ... 一一到来。

 

早上汤兄只是简单的详解了 OA 各大模块,然后选出了其中的几个小模块做练习。下面我来总结一下。

 

一、 OA 办公自动化系统

 

利用网络通讯基础及先进的网络应用平台,建设一个安全、可靠、开放、高效的信息网络和办公自动化、信息管理电子化系统,为管理部门提供现代化的日常办公条件及丰富的综合信息服务,实现档案管理自动化和办公事务处理自动化,以提高办公效率和管理水平,实现企业各部门日常业务工作的规范化、电子化、标准化,增强档案部门文书档案、人事档案、科技档案、 财务档案等档案的可管理性,实现信息的在线查询、借阅,最终实现 " 无纸 " 办公。

 

其详细资料可以查询互联网 ...

 

二、环境搭建

1. 开发环境 MyEclipse

2. 创建一个 WEB 工程         

3. 在工程下添加资源目录:

process jbpm 使用的目录

config hibernate jbpm 等工程使用的配置文件

test :单元测试类存放的目录

4. WebRoot 目录下添加:

script :脚本文件存放目录

style CSS 样式文件存放目录

5. WEB-INF 目录下添加:

pages :页面存放目录

pages/department :与部门相关的页面

pages/employee :与职员相关的页面

pages/role :与角色相关的页面,角色是一种权限分配的方法。经理、人事、秘书 ... 这就是角色,角色具有相应的权限组。比如经理具有审核员工、要员调动等权限。

6. 向工程中导入 jar 文件:

struts1 hibernate mysql jbpm junit4 相应该的 jar 文件。

可以在工程上右键 -->"MyEclipse"-->"..." ,添加相应的框架 jar 文件。

7. 向工程中添加配置文件:

Struts1 hibernater 的配置文件。

 

三、基础功能

1.DAO

WEB 应用分三层架构,这样使得程序更加易于编写与维护。三层架构并不总适合于各 WEB 应用,在某些 WEB 应用中业务逻辑简单,这样使用三层就没必要了。所以将 service dao 层合并到一起。汤兄说先搞成三层的,然后我们再看有没有必要这样搞。然后再搞成二层的。

 

我们的层与层之间使用接口连接,这样是为了可以方便的更换其中某一层的实现。比如数据访问层,我们将数据库更换为 XML 文件。但不需要修改 service 的代码。这个早就说过了,只不过今日再次提出让大家体会更深刻些。

 

汤老师使用 staruml 工具画图,接口与类的关系。我也用这个工具画一下,感觉老好了:

clip_image002

 

按照上边的关系,编写接口与实现类,这个非常简单。我们使用 hibernate 访问数据库,所以在 DaoBaseImpl 类的方法中使用 hibernate Session 进行数据库访问。

 

2. 事务管理:

在一个请求中,我们如何保证这个请求的所有操作使用的是一个 Session ?比如,一个请求同时调用了 save delete 操作。我们需要增强代码的重用,如何使得这两次调用只打开和关闭一次 Session

 

我们有什么好方法?编写一个过滤器,在调用 doFilter 之前打开一个 Session ,在调用 doFilter 返回后关闭这个 Session 。我们这个过滤器过滤一“ *.do ”的请求。但这样会导致,不需要 Session 操作数据库的请求也会创建和关闭一个 Session ,这是完全浪费资源的。但我们有一好的解决办法,看下面的实现。

 

我需要需要编写一个 HibernateSessionUtils 类,用于管理 hibernate Session

package cn.itcast.oa.utils;

 

import org.hibernate.Session;

import org.hibernate.SessionFactory;

import org.hibernate.cfg.Configuration;

 

public class HibernateSessionUtils {

    // Session 工厂

    private static SessionFactory sessionFactory = null ;

    static {

        sessionFactory = new Configuration().configure().buildSessionFactory();

    }

    // 一个请求对应一个线程,为了使一个请求统一使用一个 session

    // 所以在这里的使用 ThreadLocal ThreadLocal<Session> Map<Thread, Session> 的简化形式。

    private static ThreadLocal<Session> sessionMap = new ThreadLocal<Session>();

 

    /**

      * 取当前线程的 session

      * 即使使用了过滤器,但没有使用 Session 的请求是不会调用 getCurrentSession(true) 的。

      * @param creat

      *             true 且当 session null 时自动创建 session ,否则返回 null

      * @return

      */

    public static Session getCurrentSession( boolean creat) {

        Session session = sessionMap .get();

        if (creat && session == null ) {

            session = sessionFactory .openSession();

            // 任何地方当初次使用 Session 时便开户事务

            session.beginTransaction();

            sessionMap .set(session);

        }

        return session;

    }

 

    /**

      * 关闭和删除 session

      */

    public static void closeAndRemoveSession() {

        Session session = sessionMap .get();

        if (session != null ) {

            session.close();

            sessionMap .remove();

        }

    }

}

 

在一个请求中,我们如何保证 Session 事务的正确处理?比如,经典的银行转账示例。 Ok ,看了上边的代码,我们在初次使用 Session 时便开户事务,那何时提交或回滚事务呢?我们在过滤器中实现:

package cn.itcast.oa.web.filter;

 

import java.io.IOException;

import javax.servlet.*;

import org.hibernate.Session;

import cn.itcast.oa.utils.HibernateSessionUtils;

 

/**

  * 过滤 *.do 的请求

  * @author Administrator

  *

  */

public class HibernateSessionFilter implements Filter {

 

    public void destroy() {

    }

 

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,

            ServletException {

       

        try {

            // 继续调用 Action

            chain.doFilter(request, response);

            // 获取当前请求的 Session ,返回 null 表示当前请求没有使用 session

            Session session = HibernateSessionUtils. getCurrentSession ( false );

            if (session != null )

                // 如果当前请求使用了 seesion ,则提交事务。

                session.getTransaction().commit();  

        } catch (Exception e) {

            // 获取当前请求的 Session ,返回 null 表示当前请求没有使用 session

            Session session = HibernateSessionUtils. getCurrentSession ( false );

            if (session != null )

                // 如果当前请求使用了 seesion ,则回滚事务。

                session.getTransaction().rollback();

            throw new ServletException(e);

        } finally {

            // 关闭和删除 session

            HibernateSessionUtils. closeAndRemoveSession ();

        }

    }

 

    public void init(FilterConfig arg0) throws ServletException {

    }

}

 

使用过滤器进行 session 管理还不算是一个好的方法。因为我们还没有实现 service 层,所以在这里我们使用了 Filter 。管理 session 更好一些的方式是在 service 层中。因为 service 层中的一个方法处理一个业务逻辑请求。

 

四、 BEAN 对象管理

我们每编写一个实现类的功能时,需要进行单元测试在这里就不多说了。

 

我们在单元测试或 service 层中需要创建 Dao 的接口对象,来完成对数据的访问。如果我们直接 new DaoImpl ,这样并未实现层与层之间的分离。此时经典的工厂模式派上了用场,这个模式从 JAVA 基础增强、 JAVAWEB 到现在都有应用过。

 

我们通过工厂获取需要的接口实现类对象,但如果整个系统中共需要 100 个或者更多的不同接口实现类,难道我们需要在工厂类中添加相应数量的 getxxx 方法?汤老师经验丰富且十分有才,他使用了一个方法就可以解决获取任意接口实现类的对象:

package cn.itcast.oa.utils;

 

import java.io.*;

import java.util.Properties;

 

public class BeanFactory {

 

    /**

      * 获取指定简单接口名对应的实现类

      * <sp

转:传智播客—jbpm与OA项目(三)


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论