【整合篇】Activiti业务与流程整合之查询(二)

继上篇博客:【整合篇】JBPM4.4业务与流程整合之查询 应用第二种方式:申请实体中加入需要的相应的工作流的属性

package com.tgb.itoo.basic.entity;

import java.util.Date;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;

import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.springframework.format.annotation.DateTimeFormat;

/**
 * Entity: Leave
 *
 * @author hejingyuan IdEntity implements Serializable
 */
@Entity
@Table(name = "OA_LEAVE")
public class Leave  extends IdEntity { 

    /**
	 *
	 */
	private static final long serialVersionUID = 1L;
	private String processInstanceId;
    private String userId;
    private String testId;
    private String oldCourse;
    private String applyCourse;
    @Column
    public String getApplyCourse() {
		return applyCourse;
	}

	public void setApplyCourse(String applyCourse) {
		this.applyCourse = applyCourse;
	}

	@Column
    public String getOldCourse() {
		return oldCourse;
	}

	public void setOldCourse(String oldCourse) {
		this.oldCourse = oldCourse;
	}
	@Column
	public String getNewCourse() {
		return newCourse;
	}

	public void setNewCourse(String newCourse) {
		this.newCourse = newCourse;
	}

	private String newCourse;

    @Column
    public String getTestId() {
		return testId;
	}

	public void setTestId(String testId) {
		this.testId = testId;
	}

	@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
    private Date startTime;

    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
    private Date endTime;

   /* @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
    private Date realityStartTime;

    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
    private Date realityEndTime;*/
    private Date applyTime;
    private String leaveType;
    private String reason;

    //-- 临时属性 --//

    // 流程任务
    private Task task;

    private Map<String, Object> variables;

    // 运行中的流程实例
    private ProcessInstance processInstance;

    // 历史的流程实例
    private HistoricProcessInstance historicProcessInstance;

    // 流程定义
    private ProcessDefinition processDefinition;

    @Column
    public String getProcessInstanceId() {
        return processInstanceId;
    }

    public void setProcessInstanceId(String processInstanceId) {
        this.processInstanceId = processInstanceId;
    }

    @Column
    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "START_TIME")
    public Date getStartTime() {
        return startTime;
    }

    public void setStartTime(Date startTime) {
        this.startTime = startTime;
    }

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "END_TIME")
    public Date getEndTime() {
        return endTime;
    }

    public void setEndTime(Date endTime) {
        this.endTime = endTime;
    }

    @Column
    @Temporal(TemporalType.TIMESTAMP)
    public Date getApplyTime() {
        return applyTime;
    }

    public void setApplyTime(Date applyTime) {
        this.applyTime = applyTime;
    }

    @Column
    public String getLeaveType() {
        return leaveType;
    }

    public void setLeaveType(String leaveType) {
        this.leaveType = leaveType;
    }

    @Column
    public String getReason() {
        return reason;
    }

    public void setReason(String reason) {
        this.reason = reason;
    }

    /**
	 * 学生基础信息
	 */
	@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER, targetEntity = StudentCourseInfo.class)
	@JoinColumn(name = "studentCourseInfoId", nullable = true)
	private StudentCourseInfo studentCourseInfo;

    public StudentCourseInfo getStudentCourseInfo() {
		return studentCourseInfo;
	}

	public void setStudentCourseInfo(StudentCourseInfo studentCourseInfo) {
		this.studentCourseInfo = studentCourseInfo;
	}

	@Transient
    public Task getTask() {
        return task;
    }

    public void setTask(Task task) {
        this.task = task;
    }

    @Transient
    public Map<String, Object> getVariables() {
        return variables;
    }

    public void setVariables(Map<String, Object> variables) {
        this.variables = variables;
    }

    @Transient
    public ProcessInstance getProcessInstance() {
        return processInstance;
    }

    public void setProcessInstance(ProcessInstance processInstance) {
        this.processInstance = processInstance;
    }

    @Transient
    public HistoricProcessInstance getHistoricProcessInstance() {
        return historicProcessInstance;
    }

    public void setHistoricProcessInstance(HistoricProcessInstance historicProcessInstance) {
        this.historicProcessInstance = historicProcessInstance;
    }

    @Transient
    public ProcessDefinition getProcessDefinition() {
        return processDefinition;
    }

    public void setProcessDefinition(ProcessDefinition processDefinition) {
        this.processDefinition = processDefinition;
    }

}

在真正应用之前我们先来简单介绍一下在Activiti中比JBPM4.4的一处优化。

在activiti中,它为我们提供了一个businessKey字段。

在启动流程时,流程实例中会添加一条记录,而且流程实例表中会有一个businessKey字段,String
businessKey = leave.getId().toString();这样我们的流程表中就始终拥有业务的id,当我们再次需要的时候可以重新查询。

下面举例说明:

 /**
     * 任务列表ERROR [stderr] (http-localhost/127.0.0.1:8080-3) ScriptEngineManager providers.next(): javax.script.ScriptEngineFactory: Provider com.sun.script.javascript.RhinoScriptEngineFactory not found
     *
     * @param leave
     */
    @RequestMapping(value = "list/task")
    public ModelAndView taskList(HttpSession session, HttpServletRequest request) {
    	List<Leave> results = new ArrayList<Leave>();
    	String userId = UserUtil.getUserFromSession(session).getId();
    	results=abstractTaskList(userId);
    	return new ModelAndView("/oa/leave/taskList","results",results);                            

    }
/**
     * 抽象出来的查看任务列表,与基本业务无关
     *
     * @param userId 用户id
     * @return
     */
	public List<Leave> abstractTaskList(String userId){
		 List<Leave> results = new ArrayList<Leave>();
	     // 根据当前人的ID查询
	     TaskQuery taskQuery = taskService.createTaskQuery().taskCandidateOrAssigned(userId);
	     List<Task> tasks = taskQuery.list();
	     int i=0;

	     // 根据流程的业务ID查询实体并关联
	     for (Task task : tasks) {
	         String processInstanceId = task.getProcessInstanceId();
	         ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).active().singleResult();
	         String businessKey = processInstance.getBusinessKey();
	         if (businessKey == null) {
	             continue;
	         }
	         Leave leave=updateEntity(processInstance,task,businessKey);
	         results.add(leave);
	         i=i+1;
	     }
		return results;
	}
//更新实体
   	public Leave updateEntity(ProcessInstance processInstance,Task task,String businessKey){
   		Leave leave = leaveBean.findEntityById(businessKey);
   		leave.setProcessInstance(processInstance);
		leave.setProcessDefinition(getProcessDefinition(processInstance.getProcessDefinitionId()));
		leave.setTask(task);
		return leave;
   	}

对比:

之前的JBPM的操作方式,启动流程时将业务数据存储到流程变量中,在需要查询时,将数据从流程变量中取出,然后将取出的值赋给我们的组合实体即可。这样做的弊端在于数据可能会出现不同步的情况,但是应该并不多见。

其实使用这种方式呢,即使在实体层添加了工作流的属性,但是并不需要在真正的数据库表中添加相应的字段,那么这样做的便利在哪里呢?其实这样做主要是使得我们在返回前台数据时更加方便,我们只需要返回一个实体即可。但是弊端是什么呢,就是业务的实体中需要知道一些工作流的属性。

而且弊端不仅如此,在大型系统中,相当于实体层需要加入所有的依赖工作流的jar包,如果这个实体还需要被其他系统所依赖,那么所有的系统都会有工作流的依赖,我们曾遇到的问题就是,当我们在当前系统的实体项目中加入工作流的依赖时,由于其他系统也依赖我们本实体,导致所有的系统均瘫痪jboss不能正常启动,报不识别工作流的类。这种影响就是深远的,所以我们要实现的还是解耦。

下篇继续

时间: 2024-08-07 17:00:55

【整合篇】Activiti业务与流程整合之查询(二)的相关文章

【整合篇】Activiti业务与流程整合之查询(三)

继前两篇博客:应用第三种方式 实体中不需要引入任何与工作流相关的任何属性,单纯的做好自己即可!例如如下申请实体(Leave): package com.tgb.itoo.basic.entity; import java.util.Date; import java.util.HashSet; import java.util.Map; import java.util.Set; import javax.persistence.CascadeType; import javax.persist

【整合篇】Activiti业务与流程的整合

对于无论是Activtit还是jbpm来说,业务与流程的整合均类似,启动流程是绑定业务,流程与业务的整合放到动态代理中 [java] view plain copy print? /** * 启动修改课程流程Leave leave, * * @param leave */ @RequestMapping(value = "start", method = RequestMethod.POST) public String startWorkflow(Leave leave,Redire

【整合篇】JBPM4.4业务与流程整合之查询

我们都知道在应用工作流的过程中业务与流程的整合必不可少,那么查询时流程结合业务的查询就更是在所难免了,如何实现这种效果呢,方式有多种,下面我先简单介绍一二(目前有3种方式解决,先简单介绍一种,剩下的两种会结合Activiti再来说明). 第一种方式: Application(申请实体): package com.hjy.ssh.beans; import java.util.Date; import java.util.HashSet; import java.util.Set; public

【整合篇】JBPM4.4业务与流程的整合

在这次学习工作流的过程中,工作流如何与业务结合有多种方式,虽然很简单,但是每次都要再次梳理几分钟,这次拿出来整理一下,将它真正成为自己的知识. 从启动流程开始说: 申请页面:选择所用流程(即画的流程图的id) <table cellpadding="0" cellspacing="0" class="mainForm"> <tr> <td width="120px"> <div>

activiti自定义流程之整合(四):整合自定义表单部署流程定义

综合前几篇博文内容,我想在整合这一部分中应该会有很多模块会跳过不讲,就如自定义表单的表单列表那一块,因为这些模块在整合的过程中都几乎没有什么改动,再多讲也是重复无用功. 正因为如此,在创建了流程模型之后,模型列表的展示也是和之前的没有什么区别,而且都是很简单的后台查询以及前台展示,这一部分也就不过多的讲了. 模型列表页面如下: 至于其中的修改和删除也没什么多讲的,删除很简单,而修改也是activiti-modeler实现的主要功能,我们只需要跳转过去就行. 重要的部分在于部署,因为点击部署到达后

如何将云存储与工作流程整合?

由于云存储的出现,我们的文件不再局限于电脑的硬盘驱动器中.现在,我们 可以在笔记本电脑.平板电脑.智能手机,甚至是便携式迷你电脑上完成工作.尽管如此,很多用户仍然没有完全将云计算整合到其日常工作中.下面让我们看看如 何无缝地将云计算整合到人们的工作流程中,我们将从最关键的部分开始:选择与自身的存储介质最为匹配的云服务. 云存储服务 云存储服务多种多样,市场上有很多潜在的解决方案可供选择,并且每天都有新的服务进入云存储市场.在这些服务中,有些服务非常值得选择,可以帮助我们像是用硬盘一样简单地使用云

框架 day58 BOS项目练习(基于activiti物流配送流程,启动,查询,办理,项目知识点复习)

BOS项目笔记第12天 内容: 1.设计物流配送流程 2.启动物流配送流程 3.查询组任务.拾取组任务 4.查询个人任务.办理个人任务 1.    设计物流配送流程     物流配送流程 基于组任务进行任务分配.使用排他网关,分支选择使用流程变量实现 Activiti图形界面中: Process的Id值 对应流程定义表中的key值,可以用于启动最新版本的流程实例 任务节点中: General的 Id值对应任务表中的Task_def_key既 taskDefinitionKey值,用于定义项目中

GL_总账完整会计周期业务(流程)

2014-06-02 BaoXinjian 一. 会计业务周期的业务总论 1. 打开总帐会计期 2. 录入手工凭证,包括:        * 手工标准凭证         * 外币凭证         * 统计凭证3. 从子模块引入凭证,如:应收.应付.库存等模块4. 利用定义好的经常性凭证模板生成凭证 经常性凭证模板包括:         * 框架凭证模板-有固定帐户无金额(生成须手工填写)         * 标准凭证模板-固定帐户和固定金额         * 公式凭证模板-有固定帐户,金

Python学习(二):入门篇:python中流程控制与函数编写

python中流程控制与函数编写 Last Eidt 2014/5/2 转载请注明出处http://blog.csdn.net/jxlijunhao 一,流程控制 1)布尔逻辑 Python中利用True来表示逻辑真,False来逻辑假 not :非 and:与 or   :或 ==  :逻辑等 >>> False==True False >>> False==False True >>> not False True >>> Fal