jbpm5 开发实例


1、开发环境搭建 1.1 必须安装的软件 1) jbpm-4.4.zip 2) jdk 5 或者更高版本 3) 支持的数据库有 hsqldb、mysql、oracle、postgresql、sybase,本说明以 oracle 作为数据库。 4) GPD 插件(jbpm 在 IDE 中的流程设计器), eclipse(建议 3.6 版本以上)或 者 myeclipse ( 建 议 8.1 版本以上)安装插件所需的 zip 在 解 压 后 jbpm-4.4\install\src\gpd 中的 jbpm-gpd-site.zip,本说明以 eclipse3.6 为 例。 1.2 配置 JBPM 运行时 1) 打开 window  preferences 2) 选择 JBoss jBPM --> jBPM 4 --> Runtime Locations 3) 点击 Add... 4) 在 Add Location 对话框中,输入一个名字,比如 jbpm-4.0 然后点击 Search... 5) 在 Browse For Folder 对话框中,选择你的 jbpm 根目录,然后点击 OK 6) 点击 OK 在 Add Location 对话框中 1.3 定义 jBPM 用户库 1) 点击窗口 --> 属性(Windows --> Preferences) 2) 选择 Java --> 创建路径 --> 用户类库(Java --> Build Path --> User Libraries) 3) 点击新建(New) 4) 类型名字 jBPM Libraries 5) 点击添加 JARs(Add JARs...) 6) 找到 jBPM 安装程序下的 lib 目录 7) 选择 lib 下的所有 jar 文件并点击打开(Open) 8) 选择 jBPM Libraries 作为入口 9) 重新点击添加 JARs(Add JARs) 10) 在 jBPM 的安装程序的根目录下选择 jbpm.jar 文件 11) 点击打开(Open) 12) 在 jbpm.jar 下选择源码附件(Source attachment)作为入口 13) 点击编辑(Edit) 14) 在源码附件的配置(Source Attachment Configuration)对话框中,点击 目录(External Folder...) 15) 找到 jBPM 安装程序下的 src 目录 16) 点击选择(Choose) 17) 点击两次'确定'(Ok)会关闭所有对话框 1.4 在目录中添加 jPDL4 模式 如果你想直接编辑 XML 源码, 最好是在你的 XML 目录中指定一下模式 (schema),这样当你在编辑流程源码的时候,可以更好的帮助你编写代码。 1) 点击窗口 --> 属性(Windows --> Preferences) 2) 选择 XML --> 目录(XML --> CataLog) 3) 点击添加(Add) 4) 添加 XML 目录(Add XML Catalog Entry)的窗口打开 5) 点击 map-icon 的图标下面的按钮并选择文件系统(File System) 6) 在打开的对话框中, 选择 jBPM 安装目录下 src 文件夹中 jpdl.xsd 文件 7) 点击打开(Open)并且关闭所有的对话框 2、实例教程讲解 这节我们将使用建立一个简单请假流程项目 2.1 建立项目 在 eclipse 中新建一个 Dynamic Web Project 的项目 jbpm4leave。 2.2 加入 jbpm 用户库 1)邮件点击新建的项目 jbpm4leave—>Properties 2)如下图说示加入用户库 2.3 加入 jbpm 所需要的配置文件 大家可以从 jbpm-4.4 解压后的文件下,在路径\examples\src 中找到以下文件,加入到 项目工程的 src 中 其中 jbpm.hibernate.cfg.xml 是配置 jbpm4.4 的 hibernate 配置文件,包括数据源的配 置,和一般的 hibernate.cfg.xml 配置文件差不多。Jbpm.mailkit 开头的文件,是用于邮 件功能的配置。 2.4 新建简单的请假流程 1)新建一个 jbpm4.4 的流程定义文件 右键点击 srcNewOther,选择 JBoss jBPM 下的 Jbpm 4 Process Definition,文 件名写 leave,版本号写 4.4 即可。 3)用流程设计器打开新建的 leave.jpdl.xml。 右键点击 leave.jpdl.xmlOpen WithjBPM jPDL4 Editor,,看见如下效果 3)设计请假流程 在这个简单的请假流程中,包含开始(start)、结束(end)、任务(task)、决策(decision) 四种流程元素。 流程设计如下: 4)详细设计流程中的各任务节点的流转条件 ①选中“申请”任务节点,在 properties(属性)中,General 标签的 Name(属性 值)填为“申请”,Assignment 标签的 Type 选择 assignee(参与者,选择这个,可以指 定该任务节点的直接参与者),Expression 的属性值填为#{owner}(即指定这个任务节点 的直接参与者就是这个流程的启动者)。 ②选中“经理审批”任务节点,在 properties(属性)中,General 标签的 Name(属 性值)填为“经理审批”,Assignment 标签的 Type 选择 candidate-groups(参与者, 选择这个,可以该任务节点有某个用户组来参与),Expression 的属性值填为 manager(即 指定这个任务节点的有 manager 这个用户组来完成)。 ③“老板审批”节点同“经理审批”任务节点设置类似,只是 Expression 改为 boss ④设置决策节点,选中 ,在属性标签 General 中按如下所示填写: Name(节点名称),Expression(判断表达式,其中 day 是在流程流转过程中的一个记录 天数的属性,整个表达式的意思是天数大于 3 天需要老板审批,如果天数不大于 3 天,经 理审批通过后就直接结束流程,不需要老板审批)。 ⑤设计好流程后,点击保存,IDE 将自动为你生成一个 png 的流程图片,切记不可在 xml 源码界面进行保存,否则会生成不完整的流程图片。 ⑥在点击下方的“Source”属性,即可看到流程定义文件的 xml 源码 一下是 leave.jpdl.xml 的源码: 至此工程的 src 文件下就有下面这些文件: 2.5 发布流程 Jbpm 的流程发布其实很简单,只要使用 jbpm 已经封装好的方法进行使用,即可。 我们新建一个 deploy.jsp 的页面用户发布流程。在此讲解使用 zip 文件打包发布流程。 1) 将之前建立好的 leave.jpdl.xml 和 leave.png 文件,一起打包进 leave.zip 文件。 2) deploy.jsp 代码如下: <%@ page language="java" contentType="text/html; charset=gb2312"%> <%@page import="java.io.File,java.io.FileInputStream,java.io.InputStream, java.util.zip.ZipInputStream,java.util.*,org.jbpm.api.*,java.util.zip .*"%> Insert title here <% request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); String deployFile = request.getParameter("processDef"); if (deployFile != null && deployFile != "") { //必须使用的,流程引擎 ProcessEngine processEngine = Configuration.getProcessEngine(); RepositoryService repositoryService = processEngine .getRepositoryService(); try { String file = deployFile; //将ZIP文件封转到IO流里 InputStream is = new FileInputStream(new File(file)); ZipInputStream zis = new ZipInputStream(is); //将ZIP流程文件发布到pvm(流程虚拟机中,他会把ZIP包中的xml文件和png 图片存储到数据库中) repositoryService.createDeployment() .addResourcesFromZipInputStream(zis).deploy(); zis.close(); is.close(); out.println("发布流程成功
"); out.println("返回
"); } catch (Exception e) { e.printStackTrace(); out.println("发布流程失败"); } } %> 可直接发布zip文件
3) 测试发布成功结果 4) 查看已发布成功的流程 已经有的一个查看流程的页面 task-write.jsp,源码如下: <%@ page language="java" contentType="text/html; charset=GB18030" pageEncoding="GB18030"%> <%@include file="/head.jsp"%> <% String username = (String) session.getAttribute("username"); //流程引擎 ProcessEngine processEngine = Configuration.getProcessEngine(); RepositoryService repositoryService = processEngine .getRepositoryService(); //流程定义集合 List pdList = repositoryService .createProcessDefinitionQuery().list(); %> Insert title here <% for (ProcessDefinition pd : pdList) { %> <% } %>
流程定义
流程id 流程名称 版本号 流程删除 启动流程
<%=pd.getId()%> <%=pd.getName()%> <%=pd.getVersion()%> 删除流程 启动 流程
5) 查看流程发布情况 6) 流程定义所设计到的表 JBPM4_DEPLOYMENT JBPM4_DEPLOYPROP //存放流程定义的版本号,使用的 jbpm 版本号,已经流程名 JBPM4_JOB //存放 timer 的定义 JBPM4_LOB //存放流程定义的 xml 和 png 图片文件 2.6 启动流程 1)启动流程,其实很简单,需要获得流程定义的 ID,使用 jbpm 已经封装好的流程启动方 法就可以了。 //start.jsp <%@page import="java.util.*,org.jbpm.api.*,java.util.*"%> <% request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); try{ //流程引擎 ProcessEngine processEngine = Configuration.getProcessEngine(); //流程实例服务 ExecutionService executionService = processEngine .getExecutionService(); Map map = new HashMap(); //插入流程中存放的数据,这里存放流程启动者的名字,参数id是流程定义的ID map.put("owner", session.getAttribute("username")); executionService.startProcessInstanceById(request .getParameter("id"), map); response.sendRedirect("task-personal-list.jsp"); }catch(Exception e){ e.printStackTrace(); } %> 2)查看代办任务 // task-personal-list.jsp <%@ page language="java" contentType="text/html; charset=GB18030" pageEncoding="GB18030"%> <%@page import="org.jbpm.api.*,org.jbpm.api.task.*"%> <%@include file="/head.jsp"%> <% String username = (String) session.getAttribute("username"); //流程引擎 ProcessEngine processEngine = Configuration.getProcessEngine(); //任务引擎 TaskService taskService = processEngine.getTaskService(); //当前用户代办的任务集合 List taskList2 = taskService.findPersonalTasks(username); %> Insert title here <% for (Task task : taskList2) { %> <% } %>
个人待办任务
流程ID 当前节点 查看详细信息 查看流程图
<%=task.getId()%> <%=task.getName()%> 查看详 细信息 查看流程图
3)实现如图: //流程列表 //流程启动后,成为当前用户的待办任务 2.7 流程办理(申请) 由于我们的流程如下,启动启动流程后,流程就进入了“申请”这个流程节点(注:流程启 动后,会在流程第一个节点所有人/所有组的代办事项中找到)。 所以,现在就要在申请中进行办理。由于我们在定义流程时如下定义了: 定义了,“申请”这个节点是有流程启动者进行办理的,form指定办理“申请”这个节点的处 理页面,用户可以自己定义处理页面。Transition指定申请流程的下一个出口。 1) 在代办事项中,我们有一行如下代码: 查看 详细信息 在这里会传一个任务ID,所以在request.jsp中必须要取得这个任务ID。 //request.jsp源码 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> Insert title here <% request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); %>
申请
申请人:
请假时间:
请假原因:
前台显示如下: 填写完内容后,页面将会提交到submit.jsp,将对提交的数据进行处理,同时流程继续流转, 所以在提交的的页面中要处理两件事情: 1、 处理用户提交数据,将数据和流程实例进行绑定 2、 将流程继续流转,提交给下一个节点办理 //submit.jsp源码如下 <%@page import="java.util.*,org.jbpm.api.*"%> <%@page import="java.sql.*" %> <% request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); %> <% ProcessEngine processEngine = Configuration.getProcessEngine(); TaskService taskService = processEngine.getTaskService(); String username = (String) session.getAttribute("username"); String taskId = request.getParameter("taskId"); String owner = request.getParameter("owner"); int day = Integer.parseInt(request.getParameter("day")); String reason = request.getParameter("reason"); String sDBDriver = "oracle.jdbc.driver.OracleDriver"; String sConnStr = "jdbc:oracle:thin:@10.142.7.9:1521:orcl"; Connection conn = null; PreparedStatement stmt = null; ResultSet rs = null; try { Class.forName(sDBDriver); conn = DriverManager.getConnection(sConnStr,"scott","scott"); conn.setAutoCommit(false); //查询待办事项列表 String sql1 = "UPDATE jbpm4_hist_task task set task.assignee_=? where task.dbid_=?"; stmt = conn.prepareStatement(sql1); stmt.setString(1,username); stmt.setString(2,taskId); stmt.executeUpdate(); conn.commit(); }catch(Exception e){ e.printStackTrace(); try{ conn.rollback(); }catch(Exception e1){ e1.printStackTrace(); } }finally{ if (stmt != null) { stmt.close(); } if (conn != null) { conn.close(); } } //将数据存储封转到map中 Map map = new HashMap(); map.put("day", day); map.put("reason", reason); //将数据和流程进行绑定,具体请看jbpm4.4API //绑定数据的同时,将现在的任务节点completeTask,既完成当前操作,将流程向下提 交 taskService.completeTask(taskId, map); response.sendRedirect("task-personal-list.jsp"); %> =========我们这里将请假的内容填写如下============= 请假四天,根据流程定义,大于四天经理审批通过后,还要老板审批才可以。 2.8 流程办理(经理审批) 请假“申请”提交后,就进入经理审批流程了。在之前的经理审批节点,我们进行如下定义: 注:form:处理经理审批的处理页面 Candidate-groups:处理当前任务节点的用户组,如果不定义则任务都在这里节点进 行 操作,还可以像“申请”节点一样,定义 assignee 的 属 性 , 但 是 candidate-groups 和 assigness 同时只能使用其中的一个。 这里定义了两个 transition,分别是“批准”和“驳回”,决定的流程的下一个流转节 点 是哪里。在具体操作中,将详细说明。 //manager.jsp 源码如下: 其中,有两点需要注意: 1)taskService.getVariable(taskId, "owner")这样的内容是,取出之前在“申请” 节点中,封装进流程实例的相应变量的值,如果你要对已有值进行修改或者要增加新值,只需要 对你当前想要变更的变量封装进 map,然后同“申请”一样绑定到流程实例中即可。 2)在页面中给出了两个 submit 提交按钮,他们的 name 相同,但是 value 不同: 这刚好和我们之前定义的流程的两个 transition 相同,他是为后面流转流程所做服务的。 <%@ page language="java" contentType="text/html; charset=gb2312"%> <%@page import="org.jbpm.api.*,org.jbpm.api.task.*"%> <%@page import="java.sql.*"%> <% request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); ProcessEngine processEngine = Configuration.getProcessEngine(); TaskService taskService = processEngine.getTaskService(); String taskId = request.getParameter("id"); Task task = taskService.getTask(taskId); %> Insert title here
经理审核
申请人: <%=taskService.getVariable(taskId, "owner")%>
请假时间:<%=taskService.getVariable(taskId, "day")%>
请假原因:<%=taskService.getVariable(taskId, "reason")%>

转办

<% String sDBDriver = "oracle.jdbc.driver.OracleDriver"; String sConnStr = "jdbc:oracle:thin:@10.142.7.9:1521:orcl"; Connection conn = null; ResultSet rs = null; PreparedStatement stmt = null; try { Class.forName(sDBDriver); conn = DriverManager.getConnection(sConnStr, "scott", "scott"); String sqlstr = "SELECT procinst.dbid_,actinst.activity_name_,actinst.start_,actinst.end_," + " actinst.htask_,histtask.assignee_" + " FROM JBPM4_HIST_ACTINST actinst," + " JBPM4_HIST_PROCINST procinst," + " JBPM4_HIST_TASK histtask" + " WHERE actinst.hproci_=procinst.dbid_" + " AND histtask.dbid_=actinst.htask_" + " AND procinst.dbid_=(" + " SELECT task.procinst_" + " FROM JBPM4_TASK task" + " INNER JOIN JBPM4_HIST_TASK hist ON hist.dbid_=task.dbid_" + " WHERE hist.dbid_=?" + " )" + " AND actinst.activity_name_!='exclusive1'" + " ORDER BY procinst.dbid_,actinst.dbid_"; stmt = conn.prepareStatement(sqlstr); stmt.setString(1, taskId); rs = stmt.executeQuery(); while (rs.next()) { %> bgcolor="green" <%}%>> <% } } catch (Exception e) { e.printStackTrace(); } finally { if (rs != null) { rs.close(); } if (stmt != null) { stmt.close(); } if (conn != null) { conn.close(); } } %>
当前实例办理情况
流程ID 节点名称 开始时间 结束时间 参与人员
<%=rs.getString(1)%> <%=rs.getString(2)%> <%=rs.getString(3)%> <%=rs.getString(4)%> <%=rs.getString(6)%>
//submit_manager.jsp 注:String result = request.getParameter("result");先取出了之前有定义的相 同name,但value不同的流程result属性,然后taskService.completeTask(taskId, result);这个用来定义流程流转到的下一个节点的节点名。 <%@page contentType="text/html;charset=UTF-8" %> <%@page import="java.util.*,org.jbpm.api.*"%> <%@page import="java.sql.*" %> <% request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); ProcessEngine processEngine = Configuration.getProcessEngine(); TaskService taskService = processEngine.getTaskService(); String username = (String) session.getAttribute("username"); String taskId = request.getParameter("taskId"); String result = request.getParameter("result"); System.err.println(taskId); //result = new String(result.getBytes("ISO-8859-1"), "UTF-8"); //操作数据库 String sDBDriver = "oracle.jdbc.driver.OracleDriver"; String sConnStr = "jdbc:oracle:thin:@10.142.7.9:1521:orcl"; Connection conn = null; PreparedStatement stmt = null; ResultSet rs = null; try { Class.forName(sDBDriver); conn = DriverManager.getConnection(sConnStr,"scott","scott"); conn.setAutoCommit(false); //查询待办事项列表 String sql1 = "UPDATE jbpm4_hist_task task set task.assignee_=? where task.dbid_=?"; stmt = conn.prepareStatement(sql1); stmt.setString(1,username); stmt.setString(2,taskId); stmt.executeUpdate(); conn.commit(); }catch(Exception e){ e.printStackTrace(); try{ conn.rollback(); }catch(Exception e1){ e1.printStackTrace(); } }finally{ if (stmt != null) { stmt.close(); } if (conn != null) { conn.close(); } } taskService.completeTask(taskId, result); response.sendRedirect("task-personal-list.jsp"); %> //操作结果: 我们在此选择“批准”,同时由于申请天数大于 3 天,将由老板进行下一个审批。 2.9 流程自动决策 “经理审批”提交后,并没有直接提交给老板。如果流程中定义了决策节点(decision), 流程虚拟机(pvm)将对其中的定义内容进行判断,判断结束后才将流程流转到相应的节 点。 在这个流程中,我们定义了一个决策节点,用于根据天数来判断,“经理审批”通过后将是“老 板审批”还是结束流程。流程决策定义如下: 注:expr:定义了流程的决策公示,其中语法同 el 表达了相同 Transition:定义了流程的流转方向。 此流程定义中 expr 的公式说明如果流程中的 day 值大于 3,下一个流程转向“老板审批”, day 值小于 3 则直接转向“结束”。 根据 jbpm4.4api 的说明,决策(decision)也可由一个来进行决策,而不用 expr 简单 的表达式来进行决策。具体请参看,jbpm4.4API 文档说明。 2.10 流程办理(老板审批) 在之前的流程定义点,我们进行如下定义: 注:form:处理老板审批的处理页面 Candidate-groups:处理当前任务节点的用户组,如果不定义则任务都在这里节点进 行 操作,还可以像“申请”节点一样,定义 assignee 的 属 性 , 但 是 candidate-groups 和 assigness 同时只能使用其中的一个。 这里定义了两个 transition,分别是“批准”和“驳回”,决定的流程的下一个流转节 点 是哪里。在具体操作中,将详细说明。 //boss.jsp 源码 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@page import="org.jbpm.api.*,org.jbpm.api.task.*"%> <%@page import="java.sql.*"%> <% ProcessEngine processEngine = Configuration.getProcessEngine(); TaskService taskService = processEngine.getTaskService(); String taskId = request.getParameter("id"); Task task = taskService.getTask(taskId); %> Insert title here
老板审核
申请人: <%=taskService.getVariable(taskId, "owner")%>
请假时间:<%=taskService.getVariable(taskId, "day")%>
请假原因:<%=taskService.getVariable(taskId, "reason")%>

<% String sDBDriver = "oracle.jdbc.driver.OracleDriver"; String sConnStr = "jdbc:oracle:thin:@10.142.7.9:1521:orcl"; Connection conn = null; ResultSet rs = null; PreparedStatement stmt = null; try { Class.forName(sDBDriver); conn = DriverManager.getConnection(sConnStr, "scott", "scott"); String sqlstr = "SELECT procinst.dbid_,actinst.activity_name_,actinst.start_,actinst.end_," + " actinst.htask_,histtask.assignee_" + " FROM JBPM4_HIST_ACTINST actinst," + " JBPM4_HIST_PROCINST procinst," + " JBPM4_HIST_TASK histtask" + " WHERE actinst.hproci_=procinst.dbid_" + " AND histtask.dbid_=actinst.htask_" + " AND procinst.dbid_=(" + " SELECT task.procinst_" + " FROM JBPM4_TASK task" + " INNER JOIN JBPM4_HIST_TASK hist ON hist.dbid_=task.dbid_" + " WHERE hist.dbid_=?" + " )" + " AND actinst.activity_name_!='exclusive1'" + " ORDER BY procinst.dbid_,actinst.dbid_"; System.out.println(sqlstr); stmt = conn.prepareStatement(sqlstr); stmt.setString(1, taskId); rs = stmt.executeQuery(); while (rs.next()) { %> bgcolor="green" <%}%>> <% } } catch (Exception e) { e.printStackTrace(); } finally { if (rs != null) { rs.close(); } if (stmt != null) { stmt.close(); } if (conn != null) { conn.close(); } } %>
当前实例办理情况
流程ID 节点名称 开始时间 结束时间 参与人员
<%=rs.getString(1)%> <%=rs.getString(2)%> <%=rs.getString(3)%> <%=rs.getString(4)%> <%=rs.getString(6)%>
// submit_boss.jsp 注:由于老板审批之后的流程出口只有一个,所以在完成当前节点任务时,除了任务 ID 外,不 需要任何参数。 <%@page import="java.util.*,org.jbpm.api.*"%> <%@page import="java.sql.*" %> <% request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); ProcessEngine processEngine = Configuration.getProcessEngine(); TaskService taskService = processEngine.getTaskService(); String taskId = request.getParameter("taskId"); String username = (String) session.getAttribute("username"); //操作数据库 String sDBDriver = "oracle.jdbc.driver.OracleDriver"; String sConnStr = "jdbc:oracle:thin:@10.142.7.9:1521:orcl"; Connection conn = null; PreparedStatement stmt = null; ResultSet rs = null; //String sql1 = "UPDATE jbpm4_hist_task task set task.assignee_=? where task.dbid_=?"; //out.println(sql1); //out.println(username); //out.println(taskId); try { Class.forName(sDBDriver); conn = DriverManager.getConnection(sConnStr,"scott","scott"); conn.setAutoCommit(false); //查询待办事项列表 String sql1 = "UPDATE jbpm4_hist_task task set task.assignee_=? where task.dbid_=?"; stmt = conn.prepareStatement(sql1); stmt.setString(1,username); stmt.setString(2,taskId); stmt.executeUpdate(); conn.commit(); }catch(Exception e){ e.printStackTrace(); try{ conn.rollback(); }catch(Exception e1){ e1.printStackTrace(); } }finally{ if (rs != null) { rs.close(); } if (stmt != null) { stmt.close(); } if (conn != null) { conn.close(); } } taskService.completeTask(taskId); response.sendRedirect("task-personal-list.jsp"); %> //操作说明 点击“完成”,将结束流程流转。 这样就完成了一个简单流程的操作。 3、 数据库表简要说明 jBPM4.4 的数据库表分成以下几类: 1)和系统相关: 这个只有 JBPM4_PROPERTY 2)和 ProcessDefinition 相关的表: 有:JBPM4_DEPLOYMENT、JBPM4_DEPLOYPROP、JBPM4_LOB 3)和开启一个 instance 相关: 有 JBPM4_EXECUTION 、 JBPM4_TASK 、 JBPM4_JOB 、 JBPM4_VARIABLE 、 JBPM4_SWIMLANE、 JBPM_PARTICIPATION 4)和历史相关的表: JBPM4_HIS_ACTINST 、 JBPM4_HIS_DETAIL 、 JBPM4_HIS_PROCINST 、 JBPM4_HIS_TASK、JBPM4_HIS_VAR 5)和用户/组相关的表有: JBPM4_ID_USER、JBPM4_ID_GROUP、JBPM4_ID_MEMBERSHIP 具体数据库的详细数据结果可以参看,随文所附的 jbpm.pdm 文 件 , 使 用 powerdesigner 打开。 4、 附录及源码 随文附带的源码:有 jbpm-4.4.zip(jbpm4.4 压缩包,其中有源码、ant 文件、API 和 官方说明文档)、jbpm4leave.zip(简单请假流程)、myjbpm4web.zip(工作流系统, 包括请假流程、简单会稿流程、合同审批流程)。两个文件都是在 eclipse3.6 环境下开 发,如果您所使用的是 myeclipse,可将 jsp 页面和配置文件通过复制、黏贴来完成工 程复制。
还剩37页未读

继续阅读

下载pdf到电脑,查找使用更方便

pdf的实际排版效果,会与网站的显示效果略有不同!!

需要 10 金币 [ 分享pdf获得金币 ] 41 人已下载

下载pdf

pdf贡献者

weicy2012

贡献于2012-04-21

下载需要 10 金币 [金币充值 ]
亲,您也可以通过 分享原创pdf 来获得金币奖励!
下载pdf