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

    xiaoxiao2021-03-25  64

    工作流的23张表是如何存取的?每一步操作逻辑是什么样子的?我们来学习一下。 一、管理流程定义 1设计流程定义文档 1.1流程图 我们之前已经看过,常见流程图如下如所示: 包含了开始节点/结束节点/任务/流向线 1.2bpmn文件 BPMN 2.0根节点是definitions节点。 这个元素中,可以定义多个流程定义(不过我们建议每个文件只包含一个流程定义, 可以简化开发过程中的维护难度)。 一个空的流程定义看起来像下面这样。注意,definitions元素 最少也要包含xmlns 和 targetNamespace的声明。 targetNamespace可以是任意值,它用来对流程实例进行分类。 说明:流程定义文档有两部分组成: 1)bpmn文件 流程规则文件。在部署后,每次系统启动时都会被解析,把内容封装成流程定义放入项目缓存中。Activiti框架结合这个xml文件自动管理流程,流程的执行就是按照bpmn文件定义的规则执行的,bpmn文件是给计算机执行用的。 2)展示流程图的图片 在系统里需要展示流程的进展图片,图片是给用户看的。 2部署流程定义(classpath路径加载文件) /**部署流程定义*/ @Test public void deploymentProcessDefinition(){ //与流程定义和部署对象相关的Service RepositoryService repositoryService=processEngine.getRepositoryService(); DeploymentBuilder deploymentBuilder=repositoryService.createDeployment();//创建一个部署对象 deploymentBuilder.name("helloWorld入门程序");//添加部署的名称 deploymentBuilder.addClasspathResource("diagrams/MyProcess.bpmn");//从classpath的资源加载,一次只能加载一个文件 deploymentBuilder.addClasspathResource("diagrams/MyProcess.png");//从classpath的资源加载,一次只能加载一个文件 Deployment deployment=deploymentBuilder.deploy();//完成部署 //打印我们的流程信息 System.out.println("部署Id:"+deployment.getId()); System.out.println("部署名称Name:"+deployment.getName()); }说明: 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格式的压缩文件 进行上传: 处理代码有所改变: /**部署流程定义(Zip)*/ @Test public void deploymentProcessDefinitionZip(){ //获得上传文件的输入流程 InputStream in=this.getClass().getClassLoader().getResourceAsStream("diagrams/MyProcess.zip"); ZipInputStream zipInputStream=new ZipInputStream(in); //获取仓库服务,从类路径下完成部署 RepositoryService repositoryService=processEngine.getRepositoryService(); DeploymentBuilder deploymentBuilder=repositoryService.createDeployment();//创建一个部署对象 deploymentBuilder.name("helloWorld入门程序");//添加部署的名称 deploymentBuilder.addZipInputStream(zipInputStream); Deployment deployment=deploymentBuilder.deploy();//完成部署 //打印我们的流程信息 System.out.println("部署Id:"+deployment.getId()); System.out.println("部署名称Name:"+deployment.getName()); } 3.查看流程定义 查询流程定义的信息 /**查看流程定义 * id:(key):(version):(随机值) * name:对应流程文件process节点的name属性 * key:对应流程文件process节点的id属性 * version:发布时自动生成的。如果是第一次发布的流程,version默认从1开始; * 如果当前流程引擎中已存在相同的流程,则找到当前key对应的最高版本号,在最高版本号上加1*/ @Test public void queryProcessDefinition() throws Exception{ //获取仓库服务对象,使用版本的升级排列,查询列表 List<ProcessDefinition> pdList=processEngine.getRepositoryService() .createProcessDefinitionQuery() //添加查询条件 //.processDefinitionId(processDefinitionId) //.processDefinitionKey(processDefinitionKey) //.processDefinitionName(processDefinitionName) //排序(可以按照id/key/name/version/Cagetory排序) .orderByProcessDefinitionVersion().asc() //.count() //.listPage(firstResult, maxResults) //.singleResult() .list();//总的结果集数量 //便利集合,查看内容 for (ProcessDefinition pd:pdList) { System.out.println("id:"+pd.getId()); System.out.println("name:"+pd.getName()); System.out.println("key:"+pd.getKey()); System.out.println("version:"+pd.getVersion()); System.out.println("resourceName:"+pd.getDiagramResourceName()); System.out.println("###########################################"); } }结果: 我们再次部署一次HelloWorld流程(用刚刚的Zip): 那么查询流程定义的信息的运行结果为: 可以看到流程定义的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中的流程定义。 /**删除流程*/ @Test public void deleteDeployment(){ //删除发布信息 String deploymentId="1"; //获取仓库服务对象 RepositoryService repositoryService=processEngine.getRepositoryService(); //普通删除,如果当前规则下有正在执行的流程,则抛异常 //repositoryService.deleteDeployment(deploymentId); //级联删除,会删除和当前规则相关的所有信息,正在执行的信息,也包括历史信息 repositoryService.deleteDeployment(deploymentId, true); }说明: 1)因为删除的是流程定义,而流程定义的部署是属于仓库服务的,所以应该先得到RepositoryService 2)如果该流程定义下没有正在运行的流程,则可以用普通删除。如果是有关联的信息,用级联删除。项目开发中使用级联删除的情况比较多,删除操作一般只开放给超级管理员使用。 5.获取流程定义文档的资源(查看流程图附件) 查询出流程定义文档。主要查的是图片,用于显示流程用。 /**查看流程附件(查看流程图片)*/ @Test public void viewImage() throws Exception{ //从仓库中找需要展示的文件 String deploymentId="1"; List<String> names=processEngine.getRepositoryService() .getDeploymentResourceNames(deploymentId); String imageName=null; for(String name:names){ System.out.println("name:"+name); if(name.indexOf(".png")>0){ imageName=name; break; } } System.out.println("imageName:"+imageName); if(imageName!=null){ File f=new File("e:/"+imageName); //通过部署ID和文件名称得到文件的输入流 InputStream in = processEngine.getRepositoryService() .getResourceAsStream(deploymentId, imageName); FileUtils.copyInputStreamToFile(in, f); } }运行结果:

    说明: 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

    转载请注明原文地址: https://ju.6miu.com/read-16928.html

    最新回复(0)