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

工作流的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

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

光仔December

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值