环境准备:

  1. JDK1.6或者更高版本
  2. 支持的数据库有:h2, mysql, oracle, postgres, mssql, db2等。
  3. 支持activiti5运行的jar包
  4. 开发环境为Eclipse3.7或者以上版本,myeclipse为8.6或者以上版本
    Eclipse安装步骤:
    本地安装:解压activiti插件:activiti-eclipse-plugin.zip,然后直接把名为activiti的文件夹拷贝到eclipse所在根目录dropins目录下,成功安装。
    如果出现不成功的情况,那么一定就是版本不兼容,如果你的eclipse版本比较高,那么建议从网上下载最新版本的插件。
    下载步骤:

MyEclipse安装步骤:
将文件解压到:%myeclipse_install_folder%\MyEclipse 9\dropins文件夹下:(%myeclipse_install_folder%代表你的myeclipse的安装文件夹)
你会看见如下图文件:

然后步骤如下图:

然后打开你的myeclipse看见如下图代表安装activiti designer成功.

Eclipse下面使用Activiti:

 使用原生的java格式创建流程
@Test
public void test()
{
ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createStandaloneProcessEngineConfiguration();
configuration.setJdbcDriver(“com.mysql.jdbc.Driver”);
configuration.setJdbcUrl(“jdbc:mysql://localhost:3306/activite?createDatabaseIfNotExist=true”);
configuration.setJdbcUsername(“root”);
configuration.setJdbcPassword(“admin”); configuration.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
configuration.buildProcessEngine();
}
 使用配置文件创建流程引擎:
@Test
public void test01()
{ ProcessEngineConfiguration.createProcessEngineConfigurationFromResource(“activiti.cfg.xml”).buildProcessEngine();
}
出现错误:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named ‘processEngineConfiguration’ is defined
错误原因分析:发现在配置文件中的bean的id写错:

由于id是在类里面固定的属性,所以这个id必须正确的固定写法。
 使用ProcessEngines.getDefaultProcessEngine()自动加载classpath下面的activiti.cfg.xml配置文件。
@Test
public void test02()
{
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
}
 流程引擎可以产生以下几种service
*可以产生RepositoryService

*可以产生RuntimeService

*可以产生TaskService
TaskService taskService = processEngine.getTaskService();
各个Service的作用:
RepositoryService 管理流程定义
RuntimeService 执行管理,包括启动、推进、删除流程实例等操作
TaskService 任务管理
HistoryService 历史管理(执行完的数据的管理)
IdentityService 组织机构管理
FormService 一个可选服务,任务表单管理
ManagerService
 部署
部署代码如下:
@Test
public void test03()
{
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RepositoryService service = processEngine.getRepositoryService();
DeploymentBuilder deploymentBuilder = service.createDeployment();
Deployment deploy = deploymentBuilder.name(“测试”).addClasspathResource(“diagrams/leave.bpmn”).deploy();
System.out.println(“部署ID:”+deploy.getId());

}

部署后数据表产生的变化:
(1.):act_re_procdef:
存放流程定义的属性信息,部署每个新的流程定义都会在这张表中增加一条记录

 ACT_RE_PROCDEF:业务流程定义数据表

  1. ID_:流程ID,由“流程编号:流程版本号:自增长ID”组成
  2. CATEGORY_:流程命名空间(该编号就是流程文件targetNamespace的属性值)
  3. NAME_:流程名称(该编号就是流程文件process元素的name属性值)
  4. KEY_:流程编号(该编号就是流程文件process元素的id属性值)
  5. VERSION_:流程版本号(由程序控制,新增即为1,修改后依次加1来完成的)
  6. DEPLOYMENT_ID_:部署编号
  7. RESOURCE_NAME_:资源文件名称
  8. DGRM_RESOURCE_NAME_:图片资源文件名称
  9. HAS_START_FROM_KEY_:是否有Start From Key
    (2):act_re_deployment
    存放流程定义的显示别名和部署时间,每部署一次增加一条记录

 ACT_RE_DEPLOYMENT:用来存储部署时需要持久化保存下来的信息

  1. ID_:部署编号,自增长
  2. NAME_:部署包的名称
  3. DEPLOY_TIME_:部署时间

(3): act_ge_property

(4):act_ge_bytearray
存储流程定义相关的部署信息。即流程定义文档的存放地。每部署一次就会增加两条记录,一条是关于bpmn规则文件的,一条是图片的(如果部署时只指定了bpmn一个文件,activiti会在部署时解析bpmn文件内容自动生成流程图)。两个文件不是很大,都是以二进制形式存储在数据库中。

 ACT_GE_BYTEARRAY:用来保存部署文件的大文本数据

  1. ID_:资源文件编号,自增长
  2. REV_INT:版本号
  3. NAME_:资源文件名称
  4. DEPLOYMENT_ID_:来自于父表ACT_RE_DEPLOYMENT的主键
  5. BYTES_:大文本类型,存储文本字节流
     启动流程定义

代码如下:
@Test
public void test04()
{
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//获取运行时服务对象
RuntimeService runtimeService = processEngine.getRuntimeService();
// 使用流程key来启动流程.
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(“myProcess”);
//打印流程id,和当前节点id System.out.println(“processInstanceID:”+processInstance.getId()+"|| activitiID:"+processInstance.getActivityId());
}
运行结果:
processInstanceID:201|| activitiID:张三
运行结果分析出:
数据表变化展示:
(1.):act_ru_task

(2.): act_ru_identitylink

(3.): act_ru_execution

(4.): act_hi_taskinst

(5.): act_hi_procinst

(6.): act_hi_identitylink

(7.): act_hi_actinst

通过数据库的分析:
发现当前数据输出:act_ru_execution
processInstanceID:201 || activitiID:张三
输出:ID_(201),ACT_ID_(张三)
 查看任务
获取任务对象,对数据表:
@Test
public void test05()
{
//启动流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//获取任务对象
TaskService taskService = processEngine.getTaskService();
//查询任务
TaskQuery query = taskService.createTaskQuery();
//List list = query.taskAssignee(“张三”).list();
List list = query.list();
for(Task task : list)
{
System.out.println(“taskID:”+task.getId()+"|| taskName:"+task.getName());
System.out.println(“taskAssigned:”+task.getAssignee());
}
}

运行结果:taskID:204|| taskName:申请请假 taskAssigned:张三
分析:从结果来看,任务部署后,走到第二个节点。
 完成任务
@Test
public void test06()
{
String taskId=“204”;
//启动流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//获取任务对象
TaskService taskService = processEngine.getTaskService();
//完成审批
taskService.complete(taskId);
}
当我执行完成任务时:那么流程实例就走到下一个节点。
此时执行【查看任务】代码段,将不会看到结果输出,此时结果已经调到下一个阶段。
但是:当查询下一个节点【办理人】时,就会输出结果:
List list = query.taskAssignee(“李四”).list();
结果如下:

taskID:302|| taskName:经理审批 taskAssigned:李四
★.可以发现id变为302,等待经理进行审批,当我们在一次完成302时,那么办理人就变为boss【王五】
下面完成代码:
taskService.complete(‘’302”);
完成302,过渡到下一个节点【老板审批】:
当我们再一次使用【李四】查询时,将查询不出任何值.

此时执行完成任务代码:
List list = query.taskAssignee(“王五”).list();
查询结果为:
taskID:402|| taskName:老板审批 taskAssigned:王五
分析:
此时taskId变为402,等待老板审批,老板一旦审批完成,那么结果就将会完全返回给申请请假办理人。
数据库表的命名
Acitiviti数据库中表的命名都是以ACT_开头的。第二部分是一个两个字符用例表的标识。此用例大体与服务API是匹配的。
 ACT_RE_:’RE’表示repository。带此前缀的表包含的是静态信息,如,流程定义,流程的资源(图片,规则等)。
 ACT_RU_
:’RU’表示runtime。这是运行时的表存储着流程变量,用户任务,变量,职责(job)等运行时的数据。Activiti只存储实例执行期间的运行时数据,当流程实例结束时,将删除这些记录。这就保证了这些运行时的表小且快。
 ACT_ID_:’ID’表示identity。这些表包含标识的信息,如用户,用户组,等等。
 ACT_HI_
:’HI’表示history。就是这些表包含着历史的相关数据,如结束的流程实例,变量,任务,等等。
 ACT_GE_*:普通数据,各种情况都使用的数据。
数据库表结构图

数据库表结构说明
 ACT_GE_PROPERTY:属性数据表。存储这个流程引擎级别的数据。

  1. NAME_:属性名称

  2. VALUE_:属性值

  3. REV_INT:版本号
     ACT_GE_BYTEARRAY:用来保存部署文件的大文本数据

  4. ID_:资源文件编号,自增长

  5. REV_INT:版本号

  6. NAME_:资源文件名称

  7. DEPLOYMENT_ID_:来自于父表ACT_RE_DEPLOYMENT的主键

  8. BYTES_:大文本类型,存储文本字节流
     ACT_RE_DEPLOYMENT:用来存储部署时需要持久化保存下来的信息

  9. ID_:部署编号,自增长

  10. NAME_:部署包的名称

  11. DEPLOY_TIME_:部署时间
     ACT_RE_PROCDEF:业务流程定义数据表

  12. ID_:流程ID,由“流程编号:流程版本号:自增长ID”组成

  13. CATEGORY_:流程命名空间(该编号就是流程文件targetNamespace的属性值)

  14. NAME_:流程名称(该编号就是流程文件process元素的name属性值)

  15. KEY_:流程编号(该编号就是流程文件process元素的id属性值)

  16. VERSION_:流程版本号(由程序控制,新增即为1,修改后依次加1来完成的)

  17. DEPLOYMENT_ID_:部署编号

  18. RESOURCE_NAME_:资源文件名称

  19. DGRM_RESOURCE_NAME_:图片资源文件名称

  20. HAS_START_FROM_KEY_:是否有Start From Key
    注:此表和ACT_RE_DEPLOYMENT是多对一的关系,即,一个部署的bar包里可能包含多个流程定义文件,每个流程定义文件都会有一条记录在ACT_REPROCDEF表内,每个流程定义的数据,都会对于ACT_GE_BYTEARRAY表内的一个资源文件和PNG图片文件。和ACT_GE_BYTEARRAY的关联是通过程序用ACT_GE_BYTEARRAY.NAME与ACT_RE_PROCDEF.NAME_完成的,在数据库表结构中没有体现。
     ACT_ID_GROUP:用来存储用户组信息。

  21. ID_:用户组名*

  22. REV_INT:版本号

  23. NAME_:用户组描述信息*

  24. TYPE_:用户组类型
     ACT_ID_MEMBERSHIP:用来保存用户的分组信息

  25. USER_ID_:用户名

  26. GROUP_ID_:用户组名
     ACT_ID_USER:

  27. ID_:用户名

  28. REV_INT:版本号

  29. FIRST_:用户名称

  30. LAST_:用户姓氏

  31. EMAIL_:邮箱

  32. PWD_:密码
     ACT_RU_EXECUTION:

  33. ID_:

  34. REV_:版本号

  35. PROC_INST_ID_:流程实例编号

  36. BUSINESS_KEY_:业务编号

  37. PARENT_ID_:

  38. PROC_DEF_ID_:流程ID

  39. SUPER_EXEC_:

  40. ACT_ID_:

  41. IS_ACTIVE_:

  42. IS_CONCURRENT_:

  43. IS_SCOPE_:
     ACT_RU_JOB:运行时定时任务数据表。

  44. ID_:

  45. REV_:版本号

  46. TYPE_:

  47. LOCK_EXP_TIME_:

  48. LOCK_OWNER_:

  49. EXCLUSIVE_:

  50. EXECUTION_ID_:

  51. PROCESS_INSTANCE_ID_:

  52. RETRIES_:

  53. EXCEPTION_STACK_ID_:

  54. EXCEPTION_MSG_:

  55. DUEDATE_:

  56. REPEAT_:

  57. HANDLER_TYPE_:

  58. HANDLER_CFG_:
     ACT_RU_TASK:运行时任务数据表。

  59. ID_:

  60. REV_:版本号

  61. EXECUTION_ID_:

  62. PROC_INST_ID_:流程实例编号

  63. PROC_DEF_ID_: 流程ID

  64. NAME_:

  65. DESCRIPTION_:

  66. TASK_DEF_KEY_:

  67. ASSIGNEE_:

  68. PRIORITY_:

  69. CREATE_TIME_:
     ACT_RU_IDENTITYLINK:任务参与者数据表。主要存储当前节点参与者的信息。

  70. ID_:

  71. REV_:版本号

  72. GROUP_ID_:

  73. TYPE_:

  74. USER_ID_:

  75. TASK_ID_:
     ACT_RU_VARIABLE:运行时流程变量数据表。

  76. ID_:

  77. REV_:版本号

  78. TYPE_:

  79. NAME_:

  80. EXECUTION_ID_:

  81. PROC_INST_ID_:流程实例编号

  82. TASK_ID_:

  83. BYTEARRAY_ID_:

  84. DOUBLE_:

  85. LONG_:

  86. TEXT_:

  87. TEXT2_:
     ACT_HI_PROCINST:
     ACT_HI_ACTINST:
     ACT_HI_TASKINST:
     ACT_HI_DETAIL:
    结论及总结
     流程文件部署主要涉及到3个表,分别是:ACT_GE_BYTEARRAY、ACT_RE_DEPLOYMENT、ACT_RE_PROCDEF。主要完成“部署包”–>“流程定义文件”–>“所有包内文件”的解析部署关系。从表结构中可以看出,流程定义的元素需要每次从数据库加载并解析,因为流程定义的元素没有转化成数据库表来完成,当然流程元素解析后是放在缓存中的,具体的还需要后面详细研究。
     流程定义中的java类文件不保存在数据库里 。
     组织机构的管理相对较弱,如果要纳入单点登录体系内还需要改造完成,具体改造方法有待研究。
     运行时对象的执行与数据库记录之间的关系需要继续研究
     历史数据的保存及作用需要继续研究。
    流程规程管理
     发布流程
    public class ProcessDifinition {
    //抽取公共引擎
    private ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    // 发布流程
    @Test
    public void deploy()
    {
    //获取仓库服务
    RepositoryService repositoryService = processEngine.getRepositoryService();
    //创建发布配置对象.
    DeploymentBuilder deployment = repositoryService.createDeployment();
    //设置发布文件
    deployment.name(“请假流程”)//添加部署规则的显示别名
    .addClasspathResource(“diagrams/leave.bpmn”)//添加规则文件
    .addClasspathResource(“diagrams/leave.png”);//添加规则图片
    //完成部署
    deployment.deploy();
    }
    }
    流程发布后:数据表中情况(其中受影响表有3张)
    act_ge_bytearray:表中插入2条数据,分别是bpmn,和png图片。
    act_re_procdef: 插入1条数据。
    act_re_deployment:插入1条数据。
     使用ZIP进行流程发布
    @Test
    public void test01()
    {
    //获取仓库服务
    RepositoryService repositoryService = processEngine.getRepositoryService();
    //创建发布配置对象.
    DeploymentBuilder deployment = repositoryService.createDeployment();
    //获取上传文件的输入流
    InputStream in = this.getClass().getClassLoader().getResourceAsStream(“diagrams/diagrams.zip”);
    //创建ZIP业务对象
    ZipInputStream zipIn = new ZipInputStream(in);
    //设置发布文件
    deployment.name(“请假流程”)//添加部署规则的显示别名
    .addZipInputStream(zipIn);

     deployment.deploy();
    

    }
     多条件查询(id查询实例)
    public void processDefinition()
    {
    //获取仓库服务
    RepositoryService repositoryService = processEngine.getRepositoryService();
    //获取流程定义查询对象
    ProcessDefinitionQuery definitionQuery = repositoryService.createProcessDefinitionQuery();
    //添加查询条件
    List list = definitionQuery
    .processDefinitionId(“myProcess:3:704”)//以流程id来查询
    //.processDefinitionCategory("")
    //.processDefinitionKey("")
    // .processDefinitionName("")
    //.processDefinitionVersion(1).list();
    .orderByProcessDefinitionVersion().asc().list();
    // List list = definitionQuery.list();
    for(ProcessDefinition pd : list)
    { System.out.println(“PID:”+pd.getId()+","+pd.getKey()+","+pd.getName()+","+pd.getDeploymentId()+","+pd.getVersion()+","+pd.getResourceName());
    }
    }
    运行结果:
    PID:myProcess:3:704,myProcess,My process,701,3,leave.bpmn
    表数据展示:

查询所有:
@Test
public void processDefinition()
{
//获取仓库服务
RepositoryService repositoryService = processEngine.getRepositoryService();
//获取流程定义查询对象
ProcessDefinitionQuery definitionQuery = repositoryService.createProcessDefinitionQuery();
//添加查询条件
definitionQuery
.orderByProcessDefinitionVersion().asc();
//查询所有
List list = definitionQuery.list();
for(ProcessDefinition pd : list)
{ System.out.println(“PID:”+pd.getId()+","+pd.getKey()+","+pd.getName()+","+pd.getDeploymentId()+","+pd.getVersion()+","+pd.getResourceName());
} }
运行结果:
PID:myProcess:1:4,myProcess,My process,1,1,diagrams/leave.bpmn
PID:helloword:1:104,helloword,My process,101,1,diagrams/leave.bpmn
PID:myProcess:2:604,myProcess,My process,601,2,diagrams/leave.bpmn
PID:myProcess:3:704,myProcess,My process,701,3,leave.bpmn
运行结果可以看出:查询出了act_re_procdef所有数据。

 删除部署信息

代码展示:(可以看上图:发布id为101)
@Test
public void deleteDeplyment()
{
//获取仓库服务
RepositoryService repositoryService = processEngine.getRepositoryService();
//删除发布信息
String deloymentId=“101”;
//普通删除
repositoryService.deleteDeployment(deloymentId);
}
有图有真相:
发现使用发布Id进行删除后,act_re_deployment,act_re_prodef与act_ge_bytearray的3张表数据全部被删除
请看下图:
act_re_procdef:

act_ge_bytearray:

act_re_deployment:

级联删除:
级联删除会删除和当前规则相关的所有信息,包括历史。
@Test
public void deleteDeplyment()
{
//获取仓库服务
RepositoryService repositoryService = processEngine.getRepositoryService();
//删除信息,1是正在执行的流程。
String deloymentId=“1”;
/**普通删除,如果当前有正在执行的流程,那么删除就会抛出异常。
* 什么叫正在执行的流程:正在执行的流程,表示已经启动的流程,已经进入到等待审批阶段,还没有完成的task。
已经完成的流程不叫正在执行的流程。
*/
repositoryService.deleteDeployment(deloymentId, true);
}
上图上真相:
发现各个表中1被删除:

act_ge_bytearray:

act_re_procdef:

act_re_deployment:

正在执行的流程还有历史表也将被删除。
总结:
级联删除一般不建议使用,级联删除会删除历史以及其他所有相关表中的数据,如果一旦需要回复数据,将会永久丢失这些数据。
所以一般建议不要使用级联删除,就使用普通删除,如果有正在执行的流程,那么就不会删除。普通删除级联默认为false。
 查看流程附件(查看流程图片)
查看图片的几种思路:

  1. 展示图片,那么先得到图片的流。
  2. 得到out输出流,或者response的out流
  3. 使用这些流把图片文件输出到指定目录或者页面。
    首先:我们的流程附件是交给仓库管理的,那么我们还是使用仓库对象来进行查询:
    获取资源文件属性:
    @Test
    public void checkProcessImage(){
    //获取仓库服务
    RepositoryService repositoryService = processEngine.getRepositoryService();
    //从仓库中获取需要展示的文件
    String deloymentId=“601”;
    List names = repositoryService.getDeploymentResourceNames(deloymentId);
    for(String name : names)
    {
    System.out.println(name+",");
    }
    }
    结果展示:
    diagrams/leave.bpmn,
    diagrams/leave.png,
    表数据取出关系:

把图片展示到指定目录:
@Test
public void checkProcessImage(){
//获取仓库服务
RepositoryService repositoryService = processEngine.getRepositoryService();
//从仓库中获取需要展示的文件
String deloymentId=“601”;
List names = repositoryService.getDeploymentResourceNames(deloymentId);
String imageName="";
for(String name : names)
{
if(name.endsWith(".png"))
{
imageName=name;
}
}
if(imageName!=null)
{ //在d盘新建一个文件
File file = new File(“d:/”+imageName);
//获取资源文件输入流
InputStream in = repositoryService.getResourceAsStream(deloymentId, imageName);
try {
//copy
FileUtils.copyInputStreamToFile(in, file);
} catch (IOException e) {
e.printStackTrace();
}
}
}
目录图片如下图:(在d盘展示图片)

 启动流程实例
//流程实例管理
@Test
public void startProcess()
{ //获取运行时服务对象实例
RuntimeService runtimeService = processEngine.getRuntimeService();
//启动流程实例
//以流程id来启动流程实例比较麻烦,我们还需要去数据库找到相应的id,故而不建议使用
// runtimeService.startProcessInstanceById(processId);
//使用key来启动流程实例,启动方案:当有多个同名key时,默认启动版本最高的实例。
ProcessInstance pi = runtimeService.startProcessInstanceByKey(“myProcess”);
//流程实例对象,用来描述当前流程的状态 System.out.println(“pId”+pi.getId()+",activitiId"+pi.getActivityId());
}

运行结果:
pId801,activitiId张三
RuntimeService:
执行管理,包括启动、推进、删除流程实例等操作

如下图所示:

当前节点:(启动流程后正在运行的节点)

办理人:

流程实例对象总是指向当前活动节点:
ProcessInstance pi = runtimeService.startProcessInstanceByKey(“myProcess”);

ProcessInstance 流程实例对象,用来描述当前流程的状态:
流程实例对象:用来描述一次流程的实际执行
1.一个流程只有一个流程实例对象
2.流程实例对象永远指向当前活动的节点
3.1 如果是单线流程,流程实例就是Execution
3.2 如果是分支流程(并行流程),这时会在分支处产生一个Execution(root),分支流程中每个节点产生的execution,会统一挂在Execution(root)下

  1. 一个流程的流程实例的ID永远不会变
    流程实例启动后数据表:
    当流程启动时,会在执行表act_ru_execution中创建数据:
    当流程到达一个节点时,都会在act_ru_execution产生一条数据。

如果是task(任务),那么也会在任务表act_ru_task创建数据:
当流程到达一个节点时:
如果当前节点是用户任务节点,这时会在:act_ru_task中产生一条扩展数据。
扩展数据关键数据信息:
任务办理人,任务的创建时间等等。

 查看私有任务
私有任务:自定义指定的单一属性所属的任务。
根据指定单一属性查询私有任务。
代码展示:

//查看私有任务
@Test
public void queryPersonalTask() throws Exception {
//获取任务对象
TaskService taskService = processEngine.getTaskService();
//创建任务查询对象
TaskQuery query = taskService.createTaskQuery();
//指定办理人
String assignee = “张三”;
//查询
List list = query.taskAssignee(assignee).list();
for(Task task : list)
{
System.out.print(“taskID:”+task.getId()+",");
System.out.print(“assignee:”+task.getAssignee()+",");
System.out.print(“name:”+task.getName()+",");
System.out.print(“taskDefinitionKey:”+task.getTaskDefinitionKey()+",");
System.out.print(“processInstanceId:”+task.getProcessInstanceId()+",");
System.out.println(“processDefinitionId:”+task.getProcessDefinitionId());
}
}
运行结果:
taskID:804,assignee:张三,name:张三申请请假,taskDefinitionKey:张三,processInstanceId:801,processDefinitionId:myProcess:3:704
表对比:
Task:

Excution:

 完成任务
注意:当我们启动流程后,那么task任务表中机会产生数据,此数据是等待办理人提交的数据,每一个流程实例,在整个流程中只会存在一张表,例如:
当启动流程实例,task数据表中多了一条数据:

当完成804这个任务时(提交到下一个节点):
表中数据还是一条,不过id已经改变,办理人已经改变:
@Test
public void completeTask()
{
//获取任务对象
TaskService taskService = processEngine.getTaskService();
String taskId=“804”;
taskService.complete(taskId);
}
表:

节点:

同时我们看一下Execution表:

 查看公有任务
什么叫公有任务:在任务节点中有一个candidate use:候选用户,当我发布一个流程后,那么这些候选人都可见,那么这就叫公有任务。
公有任务见下图:

改变图片附件及图片id:

1.部署
//设置发布文件deployment.name("请假流程")//添加部署规则的显示别名
.addClasspathResource("diagrams/leave2.bpmn")//添加规则文件
.addClasspathResource("diagrams/leave2.png");//添加规则图片

影响的三张表:
act_ge_bytearray:成功部署附件(1002,1003)

act_re_procdef:产生一条数据

act_re_deployment:产生一条数据

2.启动

受影响的表:
首先想想:启动流程,那么流程就到达我们的任务节点,那么我们的Task任务表中必有数据,同时这又是正在执行的流程,那么我们的runtime表也必受影响,再者我们的历史表必须从启动流程开始记录流程运行变化情况,所以历史表也必受影响。
那么下面我们就看看task表和runtime表的变化情况:
act_ru_task:产生一条数据(task表也是runtime表)
由于我们使用:候选人,故而现在办理人为空,达到预期目的。

act_ru_execution:产生一条数据

act_ru_identitylink:可以在这张表看见候选人

代码展示:
//查询公有任务
@Test
public void queryCommonTask()
{
//获取任务对象
TaskService taskService = processEngine.getTaskService();
//创建任务查询对象
TaskQuery query = taskService.createTaskQuery();
//指定候选办理人
String candidateUser = “张无忌”;
//查询
List list = query.taskCandidateUser(candidateUser).list();
for(Task task : list)
{
System.out.print(“taskID:”+task.getId()+",");
System.out.print(“assignee:”+task.getAssignee()+",");
System.out.print(“name:”+task.getName()+",");
System.out.print(“taskDefinitionKey:”+task.getTaskDefinitionKey()+",");
System.out.print(“processInstanceId:”+task.getProcessInstanceId()+",");
System.out.println(“processDefinitionId:”+task.getProcessDefinitionId());
}
}
运行结果:
taskID:1304,assignee:null,name:张三申请请假,taskDefinitionKey:张三,processInstanceId:1301,processDefinitionId:leaveFlow:2:1204
 认领任务
原理:既然候选人都能看见这个任务,我们也没有办理人,那么我们只能从候选人中选择一人来执行这个任务,那么候选人中都可以来认领这个任务:
下面我们让【张无忌】来认领任务:
@Test
public void taskTask()
{
//获取任务对象
TaskService taskService = processEngine.getTaskService();
String taskId = “1304”;
String userId = “张无忌”;
//让userId来认领taskId:clain:认领
taskService.claim(taskId, userId);
System.out.println(“认领完毕!!!”);
}
下面来看看表变化:
act_ru_task:

可以发现原来为null的办理人现在为:张无忌,可以看出:认领成功。
注意:一旦任务被认领,就会变成私有(专属于一个人)的任务,其他候选人就看不到这个任务。
 查询流程状态
使用流程实例id进行查询流程状态:
@Test
public void queryProcessState()
{
//获取任务对象
RuntimeService runtimeService = processEngine.getRuntimeService();
String processInstanceId=“1301”;
ProcessInstance pi = runtimeService
.createProcessInstanceQuery()
.processInstanceId(processInstanceId)
.singleResult();
if(pi!=null)
{
System.out.println(“当前活动节点:”+pi.getActivityId());
}else
{
System.out.println(“流程已结束!”);
}
}
表数据:

 查看流程状态
//查看流程状态
@Test
public void queryProcessState()
{
//获取任务对象
RuntimeService runtimeService = processEngine.getRuntimeService();
String processInstanceId=“1301”;
ProcessInstance pi = runtimeService
.createProcessInstanceQuery()
.processInstanceId(processInstanceId)
.singleResult();
if(pi!=null)
{
System.out.println(“当前活动节点:”+pi.getActivityId());
}else
{
System.out.println(“流程已结束!”);
}
}
运行结果:
当前活动节点:张三
运行附件图:

总结:
ProcessEngineConfiguration:流程引擎配置对象(配置数据库连接信息和建表策略)
ProcessEngine:流程引擎的核心对象(检查环境是否正确,管理各种服务)
RepositoryService:仓库服务对象(管理部署信息)
RuntimeService: 运行时服务对象(管理流程的启动,流转等操作)
TaskService: 任务服务对象(Task表中的数据是Exeuction表的扩展,任务的创建时间和办理人)
部署:
DeploymentBuilder: 发布配置对象(发布的规则文件、规则图片和流程显示的别名)
ProcessDefinition: 流程定义(用来描述发布流程的整体信息)
ActivityImpl: 流程活动(用来描述一个流程中每个活动相关的信息)
运行:
Execution: 执行对象(用来描述当前活动节点的基本信息)
ProcessInstance: 流程实例对象(流程实例永远只想Execution(root)对象)
Task: 任务对象(任务创建时间和办理人)
使用案例
流程部署信息管理:

  1. 发布流程
  2. 查看流程定义 ProcessDefinitionQuery
  3. 删除流程
  4. 查看流程附件
    流程执行管理:
    1.启动流程
    2.查看任务(私有/公有)
    3.认领Claim UserId 和 TaskId
    4.办理任务 complete(taskId)
    5.查看任务状态
     流程变量

①.部署规则流程附件
@Test
public void test()
{
/**1.从classpath根目录下加载指定文件名称
* this.getClass().getClassLoader().getRsourceAsStream(“varTest.bpmn”);
* 2.从当前类路径下加载指定文件
* this.getClass().getResourceAsStream(“varTest.png”);
* 3.从classpath根目录下加载指定文件名称
* this.getClass().getResourceAsStream("/varTest.png");
*/
InputStream inputStreambpmn=this.getClass().getResourceAsStream(“varTest.bpmn”);
InputStream inputStreampng=this.getClass().getResourceAsStream(“varTest.png”);
processEngine.getRepositoryService()
.createDeployment()
.addInputStream(“varTest.bpmn”, inputStreambpmn)
.addInputStream(“varTest.png”, inputStreampng)
.deploy();
}
数据表:3张表发生变化。

可以发现:NAME_的1401为空,那是因为我们没有起别名。
其他三张表(略),情况与之前相同。
②.启动流程

代码:
//2.启动流程
@Test
public void startProcess()
{
RuntimeService runtimeService = processEngine.getRuntimeService();
String processDefinitionKey=“varTest”;
//创建流程变量
Map<String,Object> variables = new HashMap<String,Object>();
variables.put(“请假人”, “冯小刚”);
ProcessInstance pi = runtimeService.startProcessInstanceByKey(processDefinitionKey, variables);
System.out.println(“pid:”+pi.getId());
}
流程启动后表变化:流程变量表
act_ru_variable

act_ru_task(略)
act_ru_execution(略)
 查看流程变量
代码展示:
//3.查看流程变量
@Test
public void queryVar()
{

             String processInstanceId="1701";Task task = processEngine.getTaskService().createTaskQuery().taskAssignee("张三丰").processInstanceId(processInstanceId).singleResult();System.out.println(task.getAssignee());//查询流程变量String variableName="请假人";String var = (String) processEngine.getTaskService().getVariable(task.getId(), variableName);System.out.println(variableName+"="+var);
}

分析:指定查询条件及查询实例ID,查询出单一结果。
运行结果:张三丰
请假人=张翠山
有图有真相:

目前节点正停留在申请请假这个节点,等待提交请假申请。
 设置流程变量

Activiti详解与案例相关推荐

  1. Springboot 整合 Dubbo/ZooKeeper 详解 SOA 案例

    摘要: 原创出处:www.bysocket.com 泥瓦匠BYSocket 希望转载,保留摘要,谢谢! "看看星空,会觉得自己很渺小,可能我们在宇宙中从来就是一个偶然.所以,无论什么事情,仔 ...

  2. EMD算法之Hilbert-Huang Transform原理详解和案例分析

    目录 Hilbert-Huang Transform 希尔伯特-黄变换 Section I 人物简介 Section II Hilbert-Huang的应用领域 Section III Hilbert ...

  3. DL之DilatedConvolutions:Dilated Convolutions(膨胀卷积/扩张卷积)算法的简介(论文介绍)、架构详解、案例应用等配图集合之详细攻略

    DL之DilatedConvolutions:Dilated Convolutions(膨胀卷积/扩张卷积)算法的简介(论文介绍).架构详解.案例应用等配图集合之详细攻略 目录 Dilated Con ...

  4. DL之ShuffleNetV2:ShuffleNetV2算法的简介(论文介绍)、架构详解、案例应用等配图集合之详细攻略

    DL之ShuffleNetV2:ShuffleNetV2算法的简介(论文介绍).架构详解.案例应用等配图集合之详细攻略 目录 ShuffleNetV2算法的简介(论文介绍) 1.论文特点 2.基于硬件 ...

  5. DL之ShuffleNet:ShuffleNet算法的简介(论文介绍)、架构详解、案例应用等配图集合之详细攻略

    DL之ShuffleNet:ShuffleNet算法的简介(论文介绍).架构详解.案例应用等配图集合之详细攻略 相关文章 DL之ShuffleNet:ShuffleNet算法的简介(论文介绍).架构详 ...

  6. DL之MobileNetV2:MobileNetV2算法的简介(论文介绍)、架构详解、案例应用等配图集合之详细攻略

    DL之MobileNet V2:MobileNet V2算法的简介(论文介绍).架构详解.案例应用等配图集合之详细攻略 目录 MobileNetV2算法的简介(论文介绍) MobileNet V2算法 ...

  7. DL之MobileNet:MobileNet算法的简介(论文介绍)、架构详解、案例应用等配图集合之详细攻略

    DL之MobileNet:MobileNet算法的简介(论文介绍).架构详解.案例应用等配图集合之详细攻略 目录 MobileNet算法的简介(论文介绍) 1.研究背景 2.传统的模型轻量化常用的方法 ...

  8. DL之SqueezeNet:SqueezeNet算法的简介(论文介绍)、架构详解、案例应用等配图集合之详细攻略

    DL之SqueezeNet:SqueezeNet算法的简介(论文介绍).架构详解.案例应用等配图集合之详细攻略 目录 SqueezeNet算法的简介(论文介绍) 1.轻量级的CNN架构优势 2.主要特 ...

  9. DL之DenseNet:DenseNet算法的简介(论文介绍)、架构详解、案例应用等配图集合之详细攻略

    DL之DenseNet:DenseNet算法的简介(论文介绍).架构详解.案例应用等配图集合之详细攻略 目录 DenseNet算法的简介(论文介绍) DenseNet算法的架构详解 3.DenseNe ...

最新文章

  1. 虚拟机复制后需要改什么_网站改版后为什么需要每月运营维护?
  2. 2节点CentOS7 PackStack安装Newton
  3. Python爬虫开发与项目实践
  4. 软件性能测试过程详解与案例剖析_推荐软件测试书籍
  5. ASP.NET文件下载
  6. 解决spring-session升级到2.0.0报错的问题
  7. Spring Cloud简介–配置(第一部分)
  8. Python中print()函数不换行的方法
  9. 推荐系统组队学习——协同过滤
  10. 剑指offer——面试题49:把字符串转换成整数
  11. 【转参考】MySQL利用frm和ibd文件进行数据恢复
  12. matlab拟合例子,MATLAB数据拟合例子
  13. Flutter SqlLite数据库快速入门
  14. 苹果园助力爱奇艺各业务协同作战,视频平台的战争将走向何方?
  15. 【CCNA3】思科基本命令汇总+网线线序
  16. 15.6 模板全特化与偏特化(局部特化)
  17. 【机器学习基础】最大边缘分类器
  18. 菲尔兹奖得主陶哲轩:解题的策略
  19. 从0开始构建蓝牙耳机研发环境
  20. js中动态给img标签添加onclick事件

热门文章

  1. ch552开发环境配置
  2. 数据库系统原理(BNU_党德鹏_慕课)超详细听课笔记
  3. 小程序全局数据,tost弹窗
  4. Linux 内存管理篇(1)内存寻址
  5. STM32学习笔记(三)——外部中断的使用 1
  6. windows2008服务器sa密码修改,关于SQL Server 2008忘记sa密码修改sa密码的方法图解
  7. java商城项目开发背景描述_javaweb凌翊商城项目展示概述.ppt
  8. mysql怎么启用sa用户_安装SQL SERVER开启SA用户登录的方法
  9. 线程中断标志位 interrupt()、interrupted()、isInterrupted() 的认识
  10. 《23种设计模式之单例模式(4种实现)》