Activiti7_使用

news2024/9/25 20:39:49

Activiti7_使用

  • 一、Activiti7
  • 二、绘制工作流
  • 三、通过代码部署流程,再对流程进行实例化,完整运行一遍流程即可
  • 四、在springbooot中使用


一、Activiti7

  1. 为了实现后端的咨询流转功能,学习Activiti7,记录下使用的过程及遇到的问题

二、绘制工作流

  1. 使用spring3的后端项目为基础,开发工具idea 2023.3.2,jdk,jdk17。
    点此链接link去idea官网下载插件Activiti BPMN,在idea的Settings里Plugins使用install plugin from disk把刚才的jar包导进去
  2. 在bpmn文件夹下创建bpmn文件:
    !在这里插入图片描述
  3. 使用插件以画图形式编辑bpmn:
    在这里插入图片描述
    主要使用了三种部件:开始、任务、结束在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
任务的内容填写如下,连线按住右上角的箭头拖拽到目标即可,里面的${user}表明设置为user的变量,一会可以在使用的时候绑定用户:
在这里插入图片描述
其中的分支路线我们直接使用两个互斥条件判断,不使用排他网关:
在这里插入图片描述在这里插入图片描述

排他网关(也叫异或(XOR)网关,或叫基于数据的排他网关),用来在流程中实现决策。 当流程执行到这个网关,所有分支都会判断条件是否为 true,如果为 true 则执行该分支,注意,排他网关只会选择一个为 true 的分支执行。 (即使有两个分支条件都为 true, 排他网关也会只选择一条分支去执行)。如果从网关出去的线所有条件都不满足则系统抛出异常。说明 :经过排他网关必须要有一条且只有一条分支走。
bpmn文件绘制完成了,保存成同名png文件:在这里插入图片描述

  1. 完整的bpmn代码如下:
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/processdef">
  <process id="consult" name="consult" isExecutable="true">
    <startEvent id="sid-c41ecd07-74cd-41d5-9d7e-046bf71954c1"/>
    <userTask id="sid-7e47fd72-c056-43f6-8575-c229ff5b58b4" name="用户填写咨询表单" activiti:assignee="${user}">
      <documentation>用户填写咨询表单</documentation>
    </userTask>
    <userTask id="sid-03f0aec0-32b1-41e2-8826-5b8c73d51854" name="管理员指定业务人员" activiti:assignee="${admin}">
      <documentation>管理员指定业务人员</documentation>
    </userTask>
    <userTask id="sid-7b539102-6d65-479a-9958-5259a84c28b1" name="业务人员回复" activiti:assignee="${busPerson}">
      <documentation>业务人员回复</documentation>
    </userTask>
    <userTask id="sid-3af84618-4ba9-4686-a97f-6db4da96e916" name="管理员决定是否公示" activiti:assignee="${admin}">
      <documentation>管理员决定是否公示</documentation>
    </userTask>
    <endEvent id="sid-bd329163-e466-4ca7-bad1-9b95787e28a6"/>
    <sequenceFlow id="sid-c2da4d94-8eac-4acd-9cb0-16328237a136" sourceRef="sid-c41ecd07-74cd-41d5-9d7e-046bf71954c1" targetRef="sid-7e47fd72-c056-43f6-8575-c229ff5b58b4"/>
    <sequenceFlow id="sid-5be6635f-b5ef-4e0e-98af-1b35c6e085ae" sourceRef="sid-7e47fd72-c056-43f6-8575-c229ff5b58b4" targetRef="sid-03f0aec0-32b1-41e2-8826-5b8c73d51854"/>
    <sequenceFlow id="sid-5dc1e8b5-e2bc-45b7-b559-bffe2d3b5c24" sourceRef="sid-03f0aec0-32b1-41e2-8826-5b8c73d51854" targetRef="sid-7b539102-6d65-479a-9958-5259a84c28b1"/>
    <sequenceFlow id="sid-c3c3594c-d7d1-462f-b057-59b12dbeb190" sourceRef="sid-3af84618-4ba9-4686-a97f-6db4da96e916" targetRef="sid-bd329163-e466-4ca7-bad1-9b95787e28a6"/>
    <sequenceFlow id="sid-8a860827-e9ad-4c62-b931-939d312ddcd8" sourceRef="sid-7b539102-6d65-479a-9958-5259a84c28b1" targetRef="sid-03f0aec0-32b1-41e2-8826-5b8c73d51854">
      <conditionExpression>${evection.num&gt;1}</conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="sid-f4dc4277-d16a-415e-9cac-fe51d1c6ee65" sourceRef="sid-7b539102-6d65-479a-9958-5259a84c28b1" targetRef="sid-3af84618-4ba9-4686-a97f-6db4da96e916">
      <conditionExpression>${evection.num&lt;=1}</conditionExpression>
    </sequenceFlow>
  </process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_consult">
    <bpmndi:BPMNPlane bpmnElement="consult" id="BPMNPlane_consult">
      <bpmndi:BPMNShape id="shape-b1791cfb-c3c9-42a9-9bd8-b7e0a8906f99" bpmnElement="sid-c41ecd07-74cd-41d5-9d7e-046bf71954c1">
        <omgdc:Bounds x="-15.0" y="-120.0" width="30.0" height="30.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="shape-33324ea7-5905-4b2a-b615-2bfe666a0117" bpmnElement="sid-7e47fd72-c056-43f6-8575-c229ff5b58b4">
        <omgdc:Bounds x="-50.0" y="-60.0" width="100.0" height="80.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="shape-955afe5f-f9b7-40f0-887f-70aeb5afc173" bpmnElement="sid-03f0aec0-32b1-41e2-8826-5b8c73d51854">
        <omgdc:Bounds x="-50.0" y="40.0" width="100.0" height="80.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="shape-7a2e9e19-c268-4a46-af9c-aa6621dd9b86" bpmnElement="sid-7b539102-6d65-479a-9958-5259a84c28b1">
        <omgdc:Bounds x="-50.0" y="150.0" width="100.0" height="80.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="shape-86aead71-8e5b-4de3-8d8c-ca5f0dcc63ea" bpmnElement="sid-3af84618-4ba9-4686-a97f-6db4da96e916">
        <omgdc:Bounds x="-50.0" y="255.0" width="100.0" height="80.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="shape-1d13b250-9f5c-42db-a745-482b2c9acf56" bpmnElement="sid-bd329163-e466-4ca7-bad1-9b95787e28a6">
        <omgdc:Bounds x="-15.0" y="360.0" width="30.0" height="30.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="edge-c60fd374-56ca-4630-9f88-c9d61baa048b" bpmnElement="sid-c2da4d94-8eac-4acd-9cb0-16328237a136">
        <omgdi:waypoint x="0.0" y="-90.0"/>
        <omgdi:waypoint x="0.0" y="-60.0"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="edge-4a1da47a-a9b5-4db2-a8a9-002220e5c52a" bpmnElement="sid-5be6635f-b5ef-4e0e-98af-1b35c6e085ae">
        <omgdi:waypoint x="0.0" y="20.0"/>
        <omgdi:waypoint x="0.0" y="40.0"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="edge-3d9c4ead-a6cd-4aa2-82c7-ad1f20171327" bpmnElement="sid-5dc1e8b5-e2bc-45b7-b559-bffe2d3b5c24">
        <omgdi:waypoint x="0.0" y="120.0"/>
        <omgdi:waypoint x="0.0" y="150.0"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="edge-2116f8bb-51a7-4c43-a48b-7c4954868724" bpmnElement="sid-c3c3594c-d7d1-462f-b057-59b12dbeb190">
        <omgdi:waypoint x="0.0" y="335.0"/>
        <omgdi:waypoint x="0.0" y="360.0"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="edge-ce0e6fc3-032f-4333-83ec-7807846b046f" bpmnElement="sid-8a860827-e9ad-4c62-b931-939d312ddcd8">
        <omgdi:waypoint x="-50.0" y="190.0"/>
        <omgdi:waypoint x="-125.0" y="135.0"/>
        <omgdi:waypoint x="-50.0" y="80.0"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="edge-87fa2036-1930-4551-bede-92f275696c68" bpmnElement="sid-f4dc4277-d16a-415e-9cac-fe51d1c6ee65">
        <omgdi:waypoint x="0.0" y="230.0"/>
        <omgdi:waypoint x="0.0" y="242.5"/>
        <omgdi:waypoint x="0.0" y="255.0"/>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>


三、通过代码部署流程,再对流程进行实例化,完整运行一遍流程即可

需要序列化一个evection:在这里插入图片描述

package com.sumo.ipd;

import java.io.Serializable;

public class Evection implements Serializable {
    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }

    private int num;
}

在test里面创建ActivitiDemo类,内容:

package com.sumo.ipd;

import org.activiti.engine.*;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.Test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


public class ActivitiDemo {

    /**
     * 部署流程定义测试,查询,删除
     */
    @Test
    public void DeployTest() {
        // 1. 创建ProcessEngine流程引擎对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // 2、得到RepositoryService实例
        RepositoryService repositoryService = processEngine.getRepositoryService();
        // 3、使用RepositoryService进行部署,定义一个流程名字,把bpmn和png部署到数据库中
        Deployment deployment = repositoryService.createDeployment()    // 创建一个部署流程
                .name("咨询流程")                                    // 给部署流程命名
                .addClasspathResource("bpmn/consult.bpmn20.xml")        // 添加类路径下的资源文件
                .addClasspathResource("bpmn/consult.png")
                .deploy();                                                // 执行流程部署
        // 4、输出部署信息
        System.out.println("流程部署id:" + deployment.getId());
        System.out.println("流程部署名称:" + deployment.getName());
    }

    @Test
    public void queryProceccDefinition() {
        // 流程定义key
        String processDefinitionKey = "consult";
        // 创建ProcessEngine流程引擎对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // 获取repositoryService
        RepositoryService repositoryService = processEngine.getRepositoryService();
        // 查询流程定义
        ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
        //遍历查询结果
        List<ProcessDefinition> list = processDefinitionQuery.processDefinitionKey(processDefinitionKey).orderByProcessDefinitionVersion().desc().list();
        for (ProcessDefinition processDefinition : list) {
            System.out.println("------------------------");
            System.out.println(" 流 程 部 署 id : " +processDefinition.getDeploymentId());
            System.out.println("流程定义id: " + processDefinition.getId());
            System.out.println("流程定义名称: " + processDefinition.getName());
            System.out.println("流程定义key: " + processDefinition.getKey());
            System.out.println("流程定义版本: " + processDefinition.getVersion());
        }
    }

    @Test
    public void deleteDeployment() {
        // 流程部署id
        String deploymentId = "47501";
        // 通过流程引擎获取repositoryService
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        RepositoryService repositoryService = processEngine.getRepositoryService();
//        删除启动的流程实例
        RuntimeService runtimeService = processEngine.getRuntimeService();
        runtimeService.deleteProcessInstance("50001","用户撤销");
                //删除流程定义, 如果该流程定义已有流程实例启动则删除时出错
        //repositoryService.deleteDeployment(deploymentId);
        //设置true 级联删除流程定义,即使该流程有流程实例启动也可以删除,设
        //置为false非级别删除方式,如果流程
        repositoryService.deleteDeployment(deploymentId, true);
    }




    /**
     * 启动流程实例
     */
    @Test
    public void startProcessTest() {
        //businessKey用于绑定外部任务表单的id
        String businessKey = "1";
        // 1、创建ProcessEngine
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // 2、获取RunTimeService
        RuntimeService runtimeService = processEngine.getRuntimeService();

        // 流程变量的map
        Map<String, Object> variables = new HashMap<>();


        // 设定任务的负责人
        variables.put("user", "523097198902120431");
        variables.put("admin", "123456");
        variables.put("busPerson", "123456789");

        Evection evection = new Evection();
        evection.setNum(3);
        // 把流程变量的pojo放入map
        variables.put("evection",evection);


        // 3、根据流程定义Id启动流程,并获取流程实例
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("consult", businessKey, variables);

        // 输出内容
        System.out.println("流程定义id:" + processInstance.getProcessDefinitionId());
        System.out.println("流程实例id:" + processInstance.getId());
        System.out.println("当前活动Id:" + processInstance.getActivityId());
        System.out.println("businessKey==" + processInstance.getBusinessKey());
    }


    /**
     * 查询当前个人待执行的任务
     */
    public void findTaskListTest(String assignee) {
        // 1.创建流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // 2.获取TaskService
        TaskService taskService = processEngine.getTaskService();
        // 3.根据流程key 和 任务负责人 查询任务
        List<Task> list = taskService.createTaskQuery()
                .processDefinitionKey("consult")        //流程Key
                .taskAssignee(assignee)                    //只查询当前任务负责人的任务
                .list();
        Task task = taskService.createTaskQuery()
//                .processInstanceId("15001")            //流程实例id
                .processDefinitionKey("consult")     //流程Key
                .taskAssignee(assignee)                 //只查询当前任务负责人的任务
                .singleResult();
        String processInstanceId = task.getProcessInstanceId();
        // 2、获取RunTimeService
        RuntimeService runtimeService = processEngine.getRuntimeService();
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
        String businessKey = processInstance.getBusinessKey();

//        list.forEach(task -> {
            System.out.println("-----------------------------------------");
            System.out.println("流程实例id:" + task.getProcessInstanceId());
            System.out.println("任务id:" + task.getId());
            System.out.println("任务负责人:" + task.getAssignee());
            System.out.println("任务名称:" + task.getName());
            System.out.println("businessKey==" + businessKey);
//        });

        Evection eve = (Evection)taskService.getVariable(task.getId(), "evection");
        System.out.println(eve.getNum());
        System.out.println("获取流程变量成功");
    }


    /**
     * 完成个人代办任务及查询下一步
     */
    @Test
    public void completTaskTest() {
        findTaskListTest("523097198902120431");
        completTask("523097198902120431");

        findTaskListTest("123456");
        completTask2("123456");

        findTaskListTest("123456789");
        completTask("123456789");

        findTaskListTest("123456");
        completTask("123456");
    }

    /**
     * 普通的完成任务
     * @param assignee
     */
    public void completTask(String assignee) {
        // 1.创建流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // 2. 获取TaskService实例
        TaskService taskService = processEngine.getTaskService();
        // 3.根据流程key 和 任务的负责人 查询任务
        Task task = taskService.createTaskQuery()
                .processDefinitionKey("consult")     //流程Key
                .taskAssignee(assignee)                 //只查询当前任务负责人的任务
                .singleResult();

        System.out.println("流程实例id:" + task.getProcessInstanceId());
        System.out.println("任务id:" + task.getId());
        System.out.println("任务负责人:" + task.getAssignee());
        System.out.println("任务名称:" + task.getName()+" 完成!");
        
        // 4.完成待办任务,参数:任务id
        taskService.complete(task.getId());
    }

    /**
     * 在完成任务时修改变量调整分支走向
     * @param assignee
     */
    public void completTask2(String assignee) {
        // 1.创建流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // 2. 获取TaskService实例
        TaskService taskService = processEngine.getTaskService();
        // 3.根据流程key 和 任务的负责人 查询任务
        Task task = taskService.createTaskQuery()
                .processDefinitionKey("consult")     //流程Key
                .taskAssignee(assignee)                 //只查询当前任务负责人的任务
                .singleResult();

        System.out.println("流程实例id:" + task.getProcessInstanceId());
        System.out.println("任务id:" + task.getId());
        System.out.println("任务负责人:" + task.getAssignee());
        System.out.println("任务名称:" + task.getName()+" 完成!");

        // 流程变量的map
        Map<String, Object> variables = new HashMap<>();

        Evection evection = new Evection();
        evection.setNum(1);
        // 把流程变量的pojo放入map
        variables.put("evection",evection);
        // 4.完成待办任务,参数:任务id
        taskService.complete(task.getId(),variables);

    }


    /**
     * 如果一个流程中有多个任务,可以用list
     */
    @Test
    public void completeTask3() {
        // 获取引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // 获取操作任务的服务 TaskService
        TaskService taskService = processEngine.getTaskService();
        // 完成 经理 '李四' 的任务
        List<Task> tasks = taskService.createTaskQuery()
                .processDefinitionKey("evection")
                .taskAssignee("李四")
                .list();  // 多个任务,用list

        for (Task task : tasks) {
            if (true) {
                // 判断是哪任务
                System.out.println("流程实例id=" + task.getProcessInstanceId());
                System.out.println("任务Id=" + task.getId());
                System.out.println("任务负责人=" + task.getAssignee());
                System.out.println("任务名称=" + task.getName());
                taskService.complete(task.getId());
            }
        }
    }
}

运行ActivitiDemo完整运行一遍流程:
1DeployTest部署流程
2startProcessTest启动流程实例
3completTaskTest运行一遍流程

四、在springbooot中使用

依赖会出现报错,需要修改pom.xml

  1. 使用log4j会和springboot本身的logback冲突,排除logback
		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <artifactId>spring-boot-starter-logging</artifactId>
                    <groupId>org.springframework.boot</groupId>
                </exclusion>
            </exclusions>
        </dependency>
  1. 已经有mybatis了,把不用的注释掉在这里插入图片描述

  2. 排除slf4j-log4j12的log4j,避免和外面的log4j冲突

		<dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>${slf4j.version}</version>
            <exclusions><!-- 排除slf4j-log4j12的log4j,避免和外面的log4j冲突 -->
                <exclusion>
                    <artifactId>log4j</artifactId>
                    <groupId>log4j</groupId>
                </exclusion>
            </exclusions>
        </dependency>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1700900.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

力扣 第 399 场周赛 解题报告 | 珂学家 | 调和级数 + 分块DP

前言 T1. 优质数对的总数 I 题型: 签到 class Solution:def numberOfPairs(self, nums1: List[int], nums2: List[int], k: int) -> int:res 0for v1 in nums1:for v2 in nums2:if v1 % (v2 * k) 0:res 1return resT2. 压缩字符串 III 思路: 模拟 感觉引入一个栈&…

通用代码生成器应用场景三,遗留项目反向工程

通用代码生成器应用场景三&#xff0c;遗留项目反向工程 如果您有一个遗留项目&#xff0c;要重新开发&#xff0c;或者源代码遗失&#xff0c;或者需要重新开发&#xff0c;但是希望复用原来的数据&#xff0c;并加快开发。 如果您的项目是通用代码生成器生成的&#xff0c;…

【量算分析工具-概述】GeoServer改造Springboot番外系列三

背景概述 GIS公司做软件产品&#xff0c;往往绕不开的是量算分析工具的开发和使用。例如做的比较好的火星科技的mars3d产品&#xff0c;如下图&#xff0c;但是往往这些工具都是利用Cesium框架进行前端计算的实现的&#xff0c;网上关于这些量算工具算法原理的文章少之又少&…

石英晶体谐振器的频率与电阻温度特性及其影响因素

石英晶体谐振器是一种常用的电子元件&#xff0c;其具有精确的谐振频率&#xff0c;广泛应用于各种电子设备中&#xff0c;如时钟、频率发生器、滤波器等。石英晶体谐振器的频率和电阻温度特性是评价其性能的重要参数。 1. 频率温度特性&#xff1a; 石英晶体谐振器的频率随温…

身为UI设计老鸟,不学点3D,好像要被潮流抛弃啦,卷起来吧。

当前3D原则在UI设计中运用的越来越多&#xff0c;在UI设计中&#xff0c;使用3D元素可以为界面带来以下几个价值&#xff1a; 增强视觉冲击力&#xff1a;3D元素可以通过立体感和逼真的效果&#xff0c;为界面增添视觉冲击力&#xff0c;使得设计更加生动、吸引人&#xff0c;并…

mac电脑用n切换node版本

一、安装 node版本管理工具 “n” sudo npm install -g n二、检查安装成功&#xff1a; n --version三、查看依赖包的所有版本号 比如: npm view webpack versions --json npm view 依赖包名 versions --json四、安装你需要的版本的node sudo n <node版本号> // 例如…

<iframe>标签的使用

前言&#xff1a; 最近做项目需要使用到腾讯位置服务&#xff08;这个之后分享&#xff09;&#xff0c;其中用到了一个之前一直没用到的标签&#xff1a;&#xff1c;iframe&#xff1e;&#xff0c;一时居然不知道这个是干什么用的。今天分享一下。 下面这段代码是我用来测试…

开发者为什么需要“不良代码”

“从未犯过错误的人也从未有过新发现。” — 塞缪尔斯迈尔斯 想象一下场景&#xff1a;苏格兰&#xff0c;1928年。可能在下雨&#xff0c;一位科学家不小心让他的培养皿被霉菌污染了&#xff0c;他并不知道这个错误最终将拯救数百万人的生命&#xff0c;这项伟大的发现就是青…

了解Hive 工作原理:Hive 是如何工作的?

一、概念 1、Hive Apache Hive 是一个分布式的容错数据仓库系统&#xff0c;可实现大规模分析和便于使用 SQL 读取、写入和管理驻留在分布式存储中的PB级数据。 Hive是建立在Hadoop之上的数据仓库框架&#xff0c;它提供了一种类SQL的查询语言—HiveQL&#xff0c;使得熟悉S…

kettle 读取记事本文件给java组件处理

kettle9.4 用到两个组件 文本文件输入 文件内容如下 文本文件输入---文件 文本文件输入---内容 注意事项&#xff1a;分隔符这里&#xff0c;我一直没注意&#xff0c;导致不管怎么读数据都读不到&#xff1b;可以用换行符&#xff0c;可以用其他的&#xff0c;视情况而定&…

[idea/git] 如何把多模块项目提交到一个仓库

一、问题 我使用idea创建项目&#xff0c;依次创建module进行开发&#xff0c;开发完毕之后&#xff0c;在github上创建仓库&#xff0c;配置后发现&#xff0c;在idea里点击提交时&#xff0c;每个模块各自记录commit&#xff0c;并且每个模块都需要配置origin地址。 二、解…

【数据结构】二叉树和堆

文章目录 一、 什么是二叉树二、 二叉树的存储结构顺序存储视图 三、 堆堆的结构及概念大堆和小堆 四、 建堆五、 堆排序六、 topk问题 一、 什么是二叉树 二叉树&#xff0c;作为一种重要的数据结构&#xff0c;由节点组成&#xff0c;每个节点可以有两个子节点&#xff0c;通…

【UE5.1 角色练习】07-AOE技能

目录 效果 步骤 一、准备技能动画 二、准备粒子特效 三、技能蓝图 四、相机震动 前言 在上一篇&#xff08;【UE5.1 角色练习】06-角色发射火球-part2&#xff09;基础上继续实现角色释放AOE技能的功能。 效果 步骤 一、准备技能动画 1. 在项目设置中添加一个操作映…

Compose Multiplatform 1.6.10 发布,解释一些小问题, Jake 大佬的 Hack

虽然一直比较关注跨平台开发&#xff0c;但其实我很少写 Compose Multiplatform 的内容&#xff0c;因为关于 Compose Multiplatform 的使用&#xff0c;其实我并没在实际生产环境上发布过&#xff0c;但是这个版本确实值得一提&#xff0c;因为该版本包含&#xff1a; iOS Bet…

Vue基础(数据绑定、export使用)

1、简介 在使用vue开发的过程中&#xff0c;经常会遇到一些容易混淆的问题&#xff0c;因此&#xff0c;在本文中进行汇总操作&#xff0c;只有通过不断总结学习&#xff0c;才能更好掌握vue的使用&#xff08;每天进步一点&#xff09;。 2、数据绑定 在js中定义数据&#xf…

基于深度学习和opencv的车牌识别系统

免费获取方式↓↓↓ 项目介绍028&#xff1a; 基于深度学习和opencv的车牌识别系统 同时利用对图片每一帧图像加入视频分析模块 图片分析模块可以依据界面按钮提示进行相应功能 视频分析模块可以根据按钮提示进行对视频的分析 &#xff08;视频模块的视频追踪处理时间较长&…

知攻善防应急响应靶机训练-Web2

前言&#xff1a; 本次应急响应靶机采用的是知攻善防实验室的Web-2应急响应靶机 靶机下载地址为&#xff1a; https://pan.quark.cn/s/4b6dffd0c51a 相关账户密码 用户:administrator 密码:Zgsfqq.com 解题过程&#xff1a; 一、攻击者的IP地址&#xff08;两个&#xff09;…

1108 String复读机

solution1 分别统计字符String的个数&#xff0c;并按照该顺序输出 #include<iostream> #include<string> #include<map> using namespace std; map<char, int> mp; void handle(char c){if(mp.count(c)){cout << c;mp[c]--;if(mp[c] 0) mp.e…

【软件开发规范篇】前言

作者介绍&#xff1a;本人笔名姑苏老陈&#xff0c;从事JAVA开发工作十多年了&#xff0c;带过大学刚毕业的实习生&#xff0c;也带过技术团队。最近有个朋友的表弟&#xff0c;马上要大学毕业了&#xff0c;想从事JAVA开发工作&#xff0c;但不知道从何处入手。于是&#xff0…

吴恩达2022机器学习专项课程C2W2:2.22 多类 softmax softmax与神经网络 softmax的代码改良 多标签分类

目录 多分类问题1.什么是多分类问题2.多分类问题案例3.二分类与多分类的区别 Softmax1. 什么是Softmax2.逻辑回归预测的计算过程3. Softmax预测的计算过程4.Softmax 回归与逻辑回归的关系5. Softmax的损失函数 softmax与神经网络1.设置Softmax层2.Softmax层的计算3.softmax激活…