Activiti5工作流——常用API与数据库的关系(未完待续)

1. ProcessEngine 流程引擎(核心)

获取方法一:通过ProcessEngines获取,默认会加载activiti.cfg.xml配置文件获取数据库连接。

ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

activiti.cfg.xml主要内容如下:

<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
	<!-- 连接数据库的配置 -->
	<property name="jdbcDriver" value="com.mysql.jdbc.Driver"></property>
	<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/db_activiti?useUnicode=true&amp;characterEncoding=utf8"></property>
	<property name="jdbcUsername" value="root"></property>
	<property name="jdbcPassword" value="root"></property>
	<!-- 没有表则创建表 -->
	<property name="databaseSchemaUpdate" value="true"></property>
</bean>

获取方法二:通过ProcessEngineConfiguration获取。

ProcessEngineConfiguration cfg = ProcessEngineConfiguration.createStandaloneProcessEngineConfiguration()
        .setJdbcDriver("com.mysql.jdbc.Driver")
        .setJdbcUrl("jdbc:mysql://localhost:3306/db_activiti")
        .setJdbcUsername("root")
        .setJdbcPassword("root")
        .setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
ProcessEngine processEngine = cfg.buildProcessEngine();

2. RepositoryService 流程存储服务

RepositoryService用于流程定义和部署模型相关。

RepositoryService repositoryService = processEngine.getRepositoryService();

创建流程模型

public void createModel() {

    String name = "请假流程模型";
    String key = "LEAVE-MODEL";
    String metaInfo = "流程描述:" + name + ",KEY是" + key;
    
    Model modelData = repositoryService.newModel();
    modelData.setMetaInfo(metaInfo);
    modelData.setName(name);
    modelData.setKey(StringUtils.defaultString(key));
    repositoryService.saveModel(modelData);
}

运行后会在以下表中生成数据
act_re_model

部署流程

// 方式一:通过加载diagrams下的bpmn和png文件部署
public void deploy() {
    Deployment deployment = repositoryService
            .createDeployment() // 创建一个部署对象
            .name("一个流程名称") // 添加部署的名称
            .addClasspathResource("diagrams/helloWorld.bpmn") // 从classpath的资源中加载,一次只能加载一个文件
            .addClasspathResource("diagrams/helloWorld.png") // 从classpath的资源中加载,一次只能加载一个文件
            .deploy(); // 完成部署
    System.out.println("部署的流程信息:" + deployment);
}

// 方式二:通过加载diagrams下的zip文件部署
public void deployByZip() {
    InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("diagrams/helloWorld.zip");
    ZipInputStream zipInputStream = null;
    if (inputStream != null) {
        zipInputStream = new ZipInputStream(inputStream);
    }
    Deployment deployment = repositoryService
            .createDeployment() // 创建一个部署对象
            .name("一个名称") // 添加部署的名称
            .addZipInputStream(zipInputStream) //指定zip格式的文件完成部署
            .deploy(); // 完成部署
    System.out.println("部署的流程信息:" + deployment);
}

// 方式三:通过输入流部署
public void deployByInputStream(){
    InputStream inputStreambpmn = this.getClass().getResourceAsStream("/diagrams/helloWorld.bpmn");
    InputStream inputStreampng = this.getClass().getResourceAsStream("/diagrams/helloWorld.png");
    Deployment deployment = processEngine.getRepositoryService()//与流程定义和部署对象相关的Service
            .createDeployment()//创建一个部署对象
            .name("哈喽我的")//添加部署的名称
            //使用资源文件的名称(要求:与资源文件的名称要一致),和输入流完成部署
            .addInputStream("helloWorld.bpmn", inputStreambpmn)
            //使用资源文件的名称(要求:与资源文件的名称要一致),和输入流完成部署
            .addInputStream("helloWorld.png", inputStreampng)
            .deploy();//完成部署
    System.out.println("部署的流程信息:" + deployment);
}

运行后会在以下表中生成数据:
act_re_deployment 部署对象表
存放流程定义的显示名和部署时间,每部署一次增加一条记录

act_re_procdef 流程定义表
存放流程定义的属性信息,部署每个新的流程定义都会在这张表中增加一条记录。
注意:当流程定义的key相同的情况下,使用的是版本升级

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

act_ge_property 主键生成策略表

查询部署对象

部署对象的查询主要是对act_re_deployment表的查询,activiti通过DeploymentQuery查询流程。

//创建一个部署对象的查询
DeploymentQuery deploymentQuery = repositoryService.createDeploymentQuery();

DeploymentQuery类中有各种方法进行查询,这里不做列出。

查询流程定义

流程的查询主要是对act_re_procdef表的查询,activiti通过ProcessDefinitionQuery查询流程。

//创建一个流程定义的查询
ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();

ProcessDefinitionQuery类中有各种方法进行查询,这里不做列出。
下面列出act_re_procdef表字段的作用(注释)。
在这里插入图片描述

使用部署ID,删除流程定义

public void deleteProcessDefinition(){
    // 部署ID
    String deploymentId = "601";
    /*
     * 不带级联的删除
     *    只能删除没有启动的流程,如果流程启动,就会抛出异常
     */
	repositoryService.deleteDeployment(deploymentId);

    /*
     * 级联删除
     * 	  不管流程是否启动,都能可以删除
     */
    repositoryService.deleteDeployment(deploymentId, true);
}

如果该流程定义下没有正在运行的流程,则可以用普通删除。如果是有关联的信息,用级联删除。项目开发中使用级联删除的情况比较多,删除操作一般只开放给超级管理员使用。

查看流程图

public void viewPicture(HttpServletResponse response) throws IOException {
    String deploymentId = "801"; // 部署ID
    String resourceName = ""; // 图片资源名称

    List<String> list = repositoryService.getDeploymentResourceNames(deploymentId);
    if(list!=null && list.size()>0){
        for(String name:list){
            if(name.contains(".png")){
                resourceName = name;
                break;
            }
        }
    }
    //获取图片的输入流
    InputStream inputStream = repositoryService.getResourceAsStream(deploymentId, resourceName);
    ServletOutputStream outputStream = response.getOutputStream();
    for (int b = -1; (b = inputStream.read()) != -1;) {
        outputStream.write(b);
    }
    outputStream.close();
    inputStream.close();
}

resourceName为act_ge_bytearray表中NAME_列的值

3. RuntimeService 流程运行控制服务

与正在执行的流程实例和执行对象相关的Service

RuntimeService runtimeService = processEngine.getRuntimeService();

启动流程实例

public void start() {
    /*
     * key对应helloworld.bpmn文件中id的属性值,即 act_re_model 和 act_re_procdef 中的 key 值
     * 之所以使用流程定义的key而不是id来启动流程实例,是因为使用key值启动默认是按照最新版本的流程定义启动
     */
    String key = "helloworld";
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(key);
    System.out.println("流程实例ID:"+processInstance.getId());
	System.out.println("流程定义ID:"+processInstance.getProcessDefinitionId());
}

运行后会在以下表中生成数据:
act_ru_execution 正在执行的执行对象表
如果是单例流程(没有分支和聚合),那么流程实例ID和执行对象ID是相同的。
一个流程的流程实例只能有一个,执行对象可以存在多个(如果存在分支和聚合)。

act_hi_procinst 流程实例历史表

act_ru_task 正在执行的任务表
只有节点是UserTask的时候,该表中才存在数据。(即“开始”、“结束”节点不算)

act_hi_taskinst 任务历史表
只有节点是UserTask的时候,该表中才存在数据。(即“开始”、“结束”节点不算)

act_hi_actinst 所有活动节点的历史表(包括“开始”、“结束”节点)

  1. 如果是单例流程,执行对象ID就是流程实例ID;
  2. 如果一个流程有分支和聚合,那么执行对象ID和流程实例ID就不相同;
  3. 一个流程中,流程实例只有一个,执行对象可以存在多个。

查询流程状态(判断流程是否结束)

public boolean processIsEnd(){
    String processInstanceId = "1001";
    ProcessInstance processInstance = runtimeService
            .createProcessInstanceQuery()//创建流程实例查询
            .processInstanceId(processInstanceId)//使用流程实例ID查询
            .singleResult();
    return processInstance == null;
}

4. TaskService 任务管理服务

与正在执行的任务相关的Service。

TaskService taskService = processEngine.getTaskService();

查询当前人的个人任务

实际上就是查询act_ru_task表的数据。

public void getMyPersonalTask() {
	String assignee = "张三"; // 当前人的姓名
    List<Task> taskList = taskService
            .createTaskQuery() // 创建任务查询对象
            .taskAssignee("") // 指定个人任务查询,指定办理人
            .list();
    if(taskList!=null && taskList.size()>0){
	    for(Task task:taskList){
	        System.out.println("任务ID:"+task.getId()); // 假设返回302
	        System.out.println("任务名称:"+task.getName());
	        System.out.println("任务的创建时间:"+task.getCreateTime());
	        System.out.println("任务的办理人:"+task.getAssignee());
	        System.out.println("流程实例ID:"+task.getProcessInstanceId());
	        System.out.println("执行对象ID:"+task.getExecutionId());
	        System.out.println("流程定义ID:"+task.getProcessDefinitionId());
	      	System.out.println("########################################################");
	    }
	}
}

完成个人任务

public void finishMyTask() {
    String taskId = "302"; //任务ID
    taskService.complete(taskId);
    System.out.println("完成任务,任务ID:"+taskId);
}

运行后以下表中数据会发生变化
act_ru_execution
如果流程实例没有结束,表中的ACT_ID_字段的值会改变,指向下一个节点;
如果流程实例结束,表中数据删除。

act_hi_procinst
如果流程实例没有结束,表中数据不变;
如果流程实例结束,表中END_TIME_记录完成时间。

act_ru_task
如果流程实例没有结束,表中的NAME_、ASSIGNEE_字段的值会改变,指向下一个节点;
如果流程实例结束,表中数据删除。

act_hi_taskinst
表新增一条历史记录,原历史记录END_TIME_记录完成时间。

act_hi_actinst
表新增一条历史记录,原历史记录END_TIME_记录完成时间。

5. HistoryService 任务管理服务

与历史数据相关的Service。

HistoryService historyService = processEngine.getHistoryService();

查询历史流程实例

public void findHistoryProcessInstance(){
    String processInstanceId = "1001";
    HistoricProcessInstance hisPI = historyService
            .createHistoricProcessInstanceQuery()//创建历史流程实例查询
            .processInstanceId(processInstanceId)//使用流程实例ID查询
            .singleResult();
    System.out.println(hisPI);
}

查询历史任务

public void findHistoryTask(){
    String taskAssignee = "张三";
    List<HistoricTaskInstance> list = historyService
            .createHistoricTaskInstanceQuery()//创建历史任务实例查询
            .taskAssignee(taskAssignee)//指定历史任务的办理人
            .list();
    if(list!=null && list.size()>0){
        for(HistoricTaskInstance hisTask:list){
            System.out.println(hisTask);
        }
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值