【Activiti工作流】7.流程定义的CRUD(上)

工作流的23张表是如何存取的?每一步操作逻辑是什么样子的?我们来学习一下。

一、管理流程定义
1设计流程定义文档
1.1流程图
我们之前已经看过,常见流程图如下如所示:
【Activiti工作流】7.流程定义的CRUD(上)_第1张图片
包含了开始节点/结束节点/任务/流向线

1.2bpmn文件
BPMN 2.0根节点是definitions节点。 这个元素中,可以定义多个流程定义(不过我们建议每个文件只包含一个流程定义, 可以简化开发过程中的维护难度)。 一个空的流程定义看起来像下面这样。注意,definitions元素 最少也要包含xmlns 和 targetNamespace的声明。 targetNamespace可以是任意值,它用来对流程实例进行分类。
【Activiti工作流】7.流程定义的CRUD(上)_第2张图片
说明:流程定义文档有两部分组成:
1)bpmn文件
流程规则文件。在部署后,每次系统启动时都会被解析,把内容封装成流程定义放入项目缓存中。Activiti框架结合这个xml文件自动管理流程,流程的执行就是按照bpmn文件定义的规则执行的,bpmn文件是给计算机执行用的。

2)展示流程图的图片
在系统里需要展示流程的进展图片,图片是给用户看的。

2部署流程定义(classpath路径加载文件)
[java] view plain copy
  1. /**部署流程定义*/  
  2. @Test  
  3. public void deploymentProcessDefinition(){  
  4.     //与流程定义和部署对象相关的Service  
  5.     RepositoryService repositoryService=processEngine.getRepositoryService();  
  6.       
  7.     DeploymentBuilder deploymentBuilder=repositoryService.createDeployment();//创建一个部署对象  
  8.     deploymentBuilder.name("helloWorld入门程序");//添加部署的名称  
  9.     deploymentBuilder.addClasspathResource("diagrams/MyProcess.bpmn");//从classpath的资源加载,一次只能加载一个文件  
  10.     deploymentBuilder.addClasspathResource("diagrams/MyProcess.png");//从classpath的资源加载,一次只能加载一个文件  
  11.       
  12.     Deployment deployment=deploymentBuilder.deploy();//完成部署  
  13.       
  14.     //打印我们的流程信息  
  15.     System.out.println("部署Id:"+deployment.getId());  
  16.     System.out.println("部署名称Name:"+deployment.getName());  
  17. }  
说明:
1)先获取流程引擎对象:在创建时会自动加载classpath下的activiti.cfg.xml
//获取流程引擎对象
//getDefaultProcessEngine方法内部会自动读取名为activiti.cfg.xml文件的配置信息
ProcessEngine processEngine=ProcessEngines.getDefaultProcessEngine();


2)首先获得默认的流程引擎,通过流程引擎获取了一个RepositoryService对象(仓库对象)

3)由仓库的服务对象产生一个部署对象配置对象,用来封装部署操作的相关配置。

4)这是一个链式编程,在部署配置对象中设置显示名,上传流程定义规则文件

5)向数据库表中存放流程定义的规则信息。

6)这一步在数据库中将操作三张表:
    a)act_re_deployment(部署对象表)
        存放流程定义的显示名和部署时间,每部署一次增加一条记录
    注:如果部署相同Key的流程,那么Version将会升级,也就是版本升级:
    图7.2.jpg
    启动该Key的流程时,默认启动最新版本(Version)的流程。


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


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


注意,部署流程定义的时候,可以把bpmn文件和png文件压缩成ZIP格式的压缩文件
进行上传:



处理代码有所改变:
[java] view plain copy
  1. /**部署流程定义(Zip)*/  
  2. @Test  
  3. public void deploymentProcessDefinitionZip(){  
  4.     //获得上传文件的输入流程  
  5.     InputStream in=this.getClass().getClassLoader().getResourceAsStream("diagrams/MyProcess.zip");  
  6.     ZipInputStream zipInputStream=new ZipInputStream(in);  
  7.     //获取仓库服务,从类路径下完成部署  
  8.     RepositoryService repositoryService=processEngine.getRepositoryService();  
  9.     DeploymentBuilder deploymentBuilder=repositoryService.createDeployment();//创建一个部署对象  
  10.     deploymentBuilder.name("helloWorld入门程序");//添加部署的名称  
  11.     deploymentBuilder.addZipInputStream(zipInputStream);  
  12.     Deployment deployment=deploymentBuilder.deploy();//完成部署  
  13.       
  14.     //打印我们的流程信息  
  15.     System.out.println("部署Id:"+deployment.getId());  
  16.     System.out.println("部署名称Name:"+deployment.getName());  
  17. }  

3.查看流程定义
查询流程定义的信息
[java] view plain copy
  1. /**查看流程定义 
  2.  *  id:(key):(version):(随机值) 
  3.  *  name:对应流程文件process节点的name属性 
  4.  *  key:对应流程文件process节点的id属性 
  5.  *  version:发布时自动生成的。如果是第一次发布的流程,version默认从1开始; 
  6.  *  如果当前流程引擎中已存在相同的流程,则找到当前key对应的最高版本号,在最高版本号上加1*/  
  7. @Test  
  8. public void queryProcessDefinition() throws Exception{  
  9.     //获取仓库服务对象,使用版本的升级排列,查询列表  
  10.     List pdList=processEngine.getRepositoryService()  
  11.                                 .createProcessDefinitionQuery()  
  12.                                 //添加查询条件  
  13.                                 //.processDefinitionId(processDefinitionId)  
  14.                                 //.processDefinitionKey(processDefinitionKey)  
  15.                                 //.processDefinitionName(processDefinitionName)  
  16.                                 //排序(可以按照id/key/name/version/Cagetory排序)  
  17.                                 .orderByProcessDefinitionVersion().asc()  
  18.                                 //.count()  
  19.                                 //.listPage(firstResult, maxResults)  
  20.                                 //.singleResult()  
  21.                                 .list();//总的结果集数量  
  22.     //便利集合,查看内容  
  23.     for (ProcessDefinition pd:pdList) {  
  24.         System.out.println("id:"+pd.getId());  
  25.         System.out.println("name:"+pd.getName());  
  26.         System.out.println("key:"+pd.getKey());  
  27.         System.out.println("version:"+pd.getVersion());  
  28.         System.out.println("resourceName:"+pd.getDiagramResourceName());  
  29.         System.out.println("###########################################");  
  30.     }  
  31. }  
结果:
【Activiti工作流】7.流程定义的CRUD(上)_第3张图片
我们再次部署一次HelloWorld流程(用刚刚的Zip):
【Activiti工作流】7.流程定义的CRUD(上)_第4张图片
那么查询流程定义的信息的运行结果为:
【Activiti工作流】7.流程定义的CRUD(上)_第5张图片
可以看到流程定义的key值相同的情况下,版本是从1开始逐次升级的
流程定义的Id是【key:版本:生成ID】
说明:
1)流程定义和部署对象相关的Service都是RepositoryService。

2)创建流程定义查询对象,可以在ProcessDefinitionQuery上设置查询的相关参数

3)调用ProcessDefinitionQuery对象的list方法,执行查询,获得符合条件的流程定义列表

4)由运行结果可以看出:
Key和Name的值为:bpmn文件process节点的id和name的属性值


5)key属性被用来区别不同的流程定义。

6)带有特定key的流程定义第一次部署时,version为1。之后每次部署都会在当前最高版本号上加1

7)Id的值的生成规则为:{processDefinitionKey}:{processDefinitionVersion}:{generated-id}, 这里的generated-id是一个自动生成的唯一的数字

8)重复部署一次,deploymentId的值以一定的形式变化
   规则act_ge_property表生成


4.删除流程定义
删除部署到activiti中的流程定义。
[java] view plain copy
  1. /**删除流程*/  
  2. @Test  
  3. public void deleteDeployment(){  
  4.     //删除发布信息  
  5.     String deploymentId="1";  
  6.     //获取仓库服务对象  
  7.     RepositoryService repositoryService=processEngine.getRepositoryService();  
  8.     //普通删除,如果当前规则下有正在执行的流程,则抛异常  
  9.     //repositoryService.deleteDeployment(deploymentId);  
  10.     //级联删除,会删除和当前规则相关的所有信息,正在执行的信息,也包括历史信息  
  11.     repositoryService.deleteDeployment(deploymentId, true);  
  12.       
  13. }  
说明:
1)因为删除的是流程定义,而流程定义的部署是属于仓库服务的,所以应该先得到RepositoryService

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


5.获取流程定义文档的资源(查看流程图附件)
查询出流程定义文档。主要查的是图片,用于显示流程用。
[java] view plain copy
  1. /**查看流程附件(查看流程图片)*/  
  2. @Test  
  3. public void viewImage() throws Exception{  
  4.     //从仓库中找需要展示的文件  
  5.     String deploymentId="1";  
  6.     List names=processEngine.getRepositoryService()  
  7.                                     .getDeploymentResourceNames(deploymentId);  
  8.     String imageName=null;  
  9.     for(String name:names){  
  10.         System.out.println("name:"+name);  
  11.         if(name.indexOf(".png")>0){  
  12.             imageName=name;  
  13.             break;  
  14.         }  
  15.     }  
  16.     System.out.println("imageName:"+imageName);  
  17.     if(imageName!=null){  
  18.         File f=new File("e:/"+imageName);  
  19.         //通过部署ID和文件名称得到文件的输入流  
  20.         InputStream in = processEngine.getRepositoryService()  
  21.                                       .getResourceAsStream(deploymentId, imageName);  
  22.         FileUtils.copyInputStreamToFile(in, f);  
  23.     }  
  24. }  
运行结果:
【Activiti工作流】7.流程定义的CRUD(上)_第6张图片

【Activiti工作流】7.流程定义的CRUD(上)_第7张图片

【Activiti工作流】7.流程定义的CRUD(上)_第8张图片


说明:
1)deploymentId为流程部署ID
2)resourceName为act_ge_bytearray表中NAME_列的值
图7.9.jpg
3)使用repositoryService的getDeploymentResourceNames方法可以获取指定部署下得所有文件的名称
图7.10.jpg
4)使用repositoryService的getResourceAsStream方法传入部署ID和资源图片名称可以获取部署下指定名称文件的输入流
5)最后的有关IO流的操作,使用FileUtils工具的copyInputStreamToFile方法完成流程流程到文件的拷贝,将资源文件以流的形式输出到指定文件夹下。

如果我们的流程需要修改应该怎么操作呢?请看下一篇

转载请注明出处:http://blog.csdn.net/acmman/article/details/60981267


0

你可能感兴趣的:(activiti)