热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

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

    

继上篇博客:【整合篇】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 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 getVariables() {
return variables;
}

public void setVariables(Map 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 results = new ArrayList();
String userId = UserUtil.getUserFromSession(session).getId();
results=abstractTaskList(userId);
return new ModelAndView("/oa/leave/taskList","results",results);

}

/**
* 抽象出来的查看任务列表,与基本业务无关
*
* @param userId 用户id
* @return
*/
public List abstractTaskList(String userId){
List results = new ArrayList();
// 根据当前人的ID查询
TaskQuery taskQuery = taskService.createTaskQuery().taskCandidateOrAssigned(userId);
List 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不能正常启动,报不识别工作流的类。这种影响就是深远的,所以我们要实现的还是解耦。


下篇继续





推荐阅读
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 本文介绍了Java高并发程序设计中线程安全的概念与synchronized关键字的使用。通过一个计数器的例子,演示了多线程同时对变量进行累加操作时可能出现的问题。最终值会小于预期的原因是因为两个线程同时对变量进行写入时,其中一个线程的结果会覆盖另一个线程的结果。为了解决这个问题,可以使用synchronized关键字来保证线程安全。 ... [详细]
  • 在Java中,我会做这样的事情:classPerson{privateRecordrecord;publicStringname(){record().get(name);}p ... [详细]
  • 本文介绍了在处理不规则数据时如何使用Python自动提取文本中的时间日期,包括使用dateutil.parser模块统一日期字符串格式和使用datefinder模块提取日期。同时,还介绍了一段使用正则表达式的代码,可以支持中文日期和一些特殊的时间识别,例如'2012年12月12日'、'3小时前'、'在2012/12/13哈哈'等。 ... [详细]
  • Spring常用注解(绝对经典),全靠这份Java知识点PDF大全
    本文介绍了Spring常用注解和注入bean的注解,包括@Bean、@Autowired、@Inject等,同时提供了一个Java知识点PDF大全的资源链接。其中详细介绍了ColorFactoryBean的使用,以及@Autowired和@Inject的区别和用法。此外,还提到了@Required属性的配置和使用。 ... [详细]
  • MPLS VP恩 后门链路shamlink实验及配置步骤
    本文介绍了MPLS VP恩 后门链路shamlink的实验步骤及配置过程,包括拓扑、CE1、PE1、P1、P2、PE2和CE2的配置。详细讲解了shamlink实验的目的和操作步骤,帮助读者理解和实践该技术。 ... [详细]
  • SpringMVC接收请求参数的方式总结
    本文总结了在SpringMVC开发中处理控制器参数的各种方式,包括处理使用@RequestParam注解的参数、MultipartFile类型参数和Simple类型参数的RequestParamMethodArgumentResolver,处理@RequestBody注解的参数的RequestResponseBodyMethodProcessor,以及PathVariableMapMethodArgumentResol等子类。 ... [详细]
  • 本文介绍了RxJava在Android开发中的广泛应用以及其在事件总线(Event Bus)实现中的使用方法。RxJava是一种基于观察者模式的异步java库,可以提高开发效率、降低维护成本。通过RxJava,开发者可以实现事件的异步处理和链式操作。对于已经具备RxJava基础的开发者来说,本文将详细介绍如何利用RxJava实现事件总线,并提供了使用建议。 ... [详细]
  • 本文介绍了Java中Currency类的getInstance()方法,该方法用于检索给定货币代码的该货币的实例。文章详细解释了方法的语法、参数、返回值和异常,并提供了一个示例程序来说明该方法的工作原理。 ... [详细]
  • java drools5_Java Drools5.1 规则流基础【示例】(中)
    五、规则文件及规则流EduInfoRule.drl:packagemyrules;importsample.Employ;ruleBachelorruleflow-group ... [详细]
  • 本文是一篇翻译文章,介绍了async/await的用法和特点。async关键字被放置在函数前面,意味着该函数总是返回一个promise。文章还提到了可以显式返回一个promise的方法。该特性使得async/await更易于理解和使用。本文还提到了一些可能的错误,并希望读者能够指正。 ... [详细]
  • 1Lock与ReadWriteLock1.1LockpublicinterfaceLock{voidlock();voidlockInterruptibl ... [详细]
  • React项目中运用React技巧解决实际问题的总结
    本文总结了在React项目中如何运用React技巧解决一些实际问题,包括取消请求和页面卸载的关联,利用useEffect和AbortController等技术实现请求的取消。文章中的代码是简化后的例子,但思想是相通的。 ... [详细]
  • VueCLI多页分目录打包的步骤记录
    本文介绍了使用VueCLI进行多页分目录打包的步骤,包括页面目录结构、安装依赖、获取Vue CLI需要的多页对象等内容。同时还提供了自定义不同模块页面标题的方法。 ... [详细]
  • 使用Spring AOP实现切面编程的步骤和注意事项
    本文介绍了使用Spring AOP实现切面编程的步骤和注意事项。首先解释了@EnableAspectJAutoProxy、@Aspect、@Pointcut等注解的作用,并介绍了实现AOP功能的方法。然后详细介绍了创建切面、编写测试代码的过程,并展示了测试结果。接着讲解了关于环绕通知的使用方法,并修改了FirstTangent类以添加环绕通知方法。最后介绍了利用AOP拦截注解的方法,只需修改全局切入点即可实现。使用Spring AOP进行切面编程可以方便地实现对代码的增强和拦截。 ... [详细]
author-avatar
立而山0605_408
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有