test(activiti): 添加 Activiti 7 流程引擎测试用例
- 新增流程部署、查询、实例初始化和任务管理等测试方法 - 添加历史记录查询功能 - 更新 NIO 服务器示例代码 - 新增枚举类型和自定义类型处理器- 调整 Spring Cloud服务配置 - 添加新的 BPMN 文件 Changes Activiti7DemoApplicationTests.java AioServer.java AmountBig.java AmountTypeHandler.java application.yaml application.yaml asdf.bpmn20.xml ASPIServiceImpl.java bootstrap.yml BProviderController.java BService.java BSPIServiceImpl.java cn.whaifree.tech.SPI.SPIService ConfigController.java FanxinTest.java FunctionInterfaceDemo.java GRRXReference.java leave.bpmn leave.png leave1.bpmn20.xml LeetCode210_207.java LeetCode469_1.java LeetCode1648.java LeetCode2602.java P1.java P1.java pom.xml pom.xml pom.xml RestConfig.java sadasf.bpmn20.xml ScheduledThreadPoolTest.java ServiceBApplication.java SPIService.java TestController.java ThreadDemo1.java TransactionConfig.java workflow.md Unversioned Files C:\Users\wenhai\project\javaProject\LeetCode\SpringCloud\GateWay\src\main\resources\application.properties C:\Users\wenhai\project\javaProject\LeetCode\SpringCloud\GateWay\src\main\java\com\whai\springcloud\gateway\GateWayApplication.java C:\Users\wenhai\project\javaProject\LeetCode\SpringCloud\GateWay\src\test\java\com\whai\springcloud\gateway\GateWayApplicationTests.java C:\Users\wenhai\project\javaProject\LeetCode\SpringCloud\GateWay\pom.xml
This commit is contained in:
parent
ea493390a6
commit
93ae3a0720
119
Activiti7Demo/src/main/resources/bpmn/asdf.bpmn20.xml
Normal file
119
Activiti7Demo/src/main/resources/bpmn/asdf.bpmn20.xml
Normal file
@ -0,0 +1,119 @@
|
||||
<?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:flowable="http://flowable.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.flowable.org/processdef">
|
||||
<!-- 流程定义 -->
|
||||
<process id="parallelApprovalProcess" name="Parallel Approval Process" isExecutable="true">
|
||||
|
||||
<!-- 开始事件 -->
|
||||
<startEvent id="startEvent" name="Start"/>
|
||||
|
||||
<!-- 并行网关(分支) -->
|
||||
<parallelGateway id="forkGateway" />
|
||||
|
||||
<!-- 财务审批任务 -->
|
||||
<userTask id="financialApproval" name="Financial Approval" flowable:assignee="financeUser" />
|
||||
|
||||
<!-- 人力资源审批任务 -->
|
||||
<userTask id="hrApproval" name="HR Approval" flowable:assignee="hrUser" />
|
||||
|
||||
<!-- 技术审批任务 -->
|
||||
<userTask id="techApproval" name="Tech Approval" flowable:assignee="techUser" />
|
||||
|
||||
<!-- 并行网关(汇合) -->
|
||||
<parallelGateway id="joinGateway" />
|
||||
|
||||
<!-- 结束事件 -->
|
||||
<endEvent id="endEvent" name="End"/>
|
||||
|
||||
<!-- 连线 -->
|
||||
<sequenceFlow id="flow1" sourceRef="startEvent" targetRef="forkGateway"/>
|
||||
<sequenceFlow id="flow2" sourceRef="forkGateway" targetRef="financialApproval"/>
|
||||
<sequenceFlow id="flow3" sourceRef="forkGateway" targetRef="hrApproval"/>
|
||||
<sequenceFlow id="flow4" sourceRef="forkGateway" targetRef="techApproval"/>
|
||||
<sequenceFlow id="flow5" sourceRef="financialApproval" targetRef="joinGateway"/>
|
||||
<sequenceFlow id="flow6" sourceRef="hrApproval" targetRef="joinGateway"/>
|
||||
<sequenceFlow id="flow7" sourceRef="techApproval" targetRef="joinGateway"/>
|
||||
<sequenceFlow id="flow8" sourceRef="joinGateway" targetRef="endEvent"/>
|
||||
</process>
|
||||
|
||||
<!-- 图形表示部分 -->
|
||||
<bpmndi:BPMNDiagram id="BPMNDiagram_parallelApprovalProcess">
|
||||
<bpmndi:BPMNPlane id="BPMNPlane_parallelApprovalProcess" bpmnElement="parallelApprovalProcess">
|
||||
|
||||
<!-- 开始事件图形 -->
|
||||
<bpmndi:BPMNShape id="startEventShape" bpmnElement="startEvent">
|
||||
<omgdc:Bounds x="100" y="100" width="36" height="36"/>
|
||||
</bpmndi:BPMNShape>
|
||||
|
||||
<!-- 并行网关(分支)图形 -->
|
||||
<bpmndi:BPMNShape id="forkGatewayShape" bpmnElement="forkGateway">
|
||||
<omgdc:Bounds x="200" y="100" width="50" height="50"/>
|
||||
</bpmndi:BPMNShape>
|
||||
|
||||
<!-- 财务审批任务图形 -->
|
||||
<bpmndi:BPMNShape id="financialApprovalShape" bpmnElement="financialApproval">
|
||||
<omgdc:Bounds x="300" y="40" width="80" height="100"/>
|
||||
</bpmndi:BPMNShape>
|
||||
|
||||
<!-- 人力资源审批任务图形 -->
|
||||
<bpmndi:BPMNShape id="hrApprovalShape" bpmnElement="hrApproval">
|
||||
<omgdc:Bounds x="300" y="150" width="80" height="100"/>
|
||||
</bpmndi:BPMNShape>
|
||||
|
||||
<!-- 技术审批任务图形 -->
|
||||
<bpmndi:BPMNShape id="techApprovalShape" bpmnElement="techApproval">
|
||||
<omgdc:Bounds x="300" y="260" width="80" height="100"/>
|
||||
</bpmndi:BPMNShape>
|
||||
|
||||
<!-- 并行网关(汇合)图形 -->
|
||||
<bpmndi:BPMNShape id="joinGatewayShape" bpmnElement="joinGateway">
|
||||
<omgdc:Bounds x="420" y="150" width="50" height="50"/>
|
||||
</bpmndi:BPMNShape>
|
||||
|
||||
<!-- 结束事件图形 -->
|
||||
<bpmndi:BPMNShape id="endEventShape" bpmnElement="endEvent">
|
||||
<omgdc:Bounds x="550" y="160" width="36" height="36"/>
|
||||
</bpmndi:BPMNShape>
|
||||
|
||||
<!-- 连线图形 -->
|
||||
<bpmndi:BPMNEdge id="flow1Edge" bpmnElement="flow1">
|
||||
<omgdi:waypoint x="136" y="118"/>
|
||||
<omgdi:waypoint x="200" y="125"/>
|
||||
</bpmndi:BPMNEdge>
|
||||
|
||||
<bpmndi:BPMNEdge id="flow2Edge" bpmnElement="flow2">
|
||||
<omgdi:waypoint x="250" y="125"/>
|
||||
<omgdi:waypoint x="300" y="90"/>
|
||||
</bpmndi:BPMNEdge>
|
||||
|
||||
<bpmndi:BPMNEdge id="flow3Edge" bpmnElement="flow3">
|
||||
<omgdi:waypoint x="250" y="125"/>
|
||||
<omgdi:waypoint x="300" y="200"/>
|
||||
</bpmndi:BPMNEdge>
|
||||
|
||||
<bpmndi:BPMNEdge id="flow4Edge" bpmnElement="flow4">
|
||||
<omgdi:waypoint x="250" y="125"/>
|
||||
<omgdi:waypoint x="300" y="310"/>
|
||||
</bpmndi:BPMNEdge>
|
||||
|
||||
<bpmndi:BPMNEdge id="flow5Edge" bpmnElement="flow5">
|
||||
<omgdi:waypoint x="380" y="90"/>
|
||||
<omgdi:waypoint x="420" y="175"/>
|
||||
</bpmndi:BPMNEdge>
|
||||
|
||||
<bpmndi:BPMNEdge id="flow6Edge" bpmnElement="flow6">
|
||||
<omgdi:waypoint x="380" y="200"/>
|
||||
<omgdi:waypoint x="420" y="175"/>
|
||||
</bpmndi:BPMNEdge>
|
||||
|
||||
<bpmndi:BPMNEdge id="flow7Edge" bpmnElement="flow7">
|
||||
<omgdi:waypoint x="380" y="310"/>
|
||||
<omgdi:waypoint x="420" y="175"/>
|
||||
</bpmndi:BPMNEdge>
|
||||
|
||||
<bpmndi:BPMNEdge id="flow8Edge" bpmnElement="flow8">
|
||||
<omgdi:waypoint x="470" y="175"/>
|
||||
<omgdi:waypoint x="550" y="178"/>
|
||||
</bpmndi:BPMNEdge>
|
||||
</bpmndi:BPMNPlane>
|
||||
</bpmndi:BPMNDiagram>
|
||||
</definitions>
|
35
Activiti7Demo/src/main/resources/bpmn/leave.bpmn
Normal file
35
Activiti7Demo/src/main/resources/bpmn/leave.bpmn
Normal file
@ -0,0 +1,35 @@
|
||||
<?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="Part1_Deployment" name="Part1_Deployment" isExecutable="true">
|
||||
<startEvent id="sid-26d6e725-878e-411d-b23d-6df4ae3cbd24"/>
|
||||
<endEvent id="sid-03d64ced-963c-4506-a5b3-21b8a9dc4279"/>
|
||||
<sequenceFlow id="sid-560ce1e7-a0f9-4a99-8a64-d2920292cd37" sourceRef="sid-26d6e725-878e-411d-b23d-6df4ae3cbd24" targetRef="sid-86ada704-a4d8-4a01-bddc-b2cd677f091d"/>
|
||||
<sequenceFlow id="sid-da2d1cc1-7544-40f6-81ab-1d0c32c0064a" sourceRef="sid-8af65ca8-f037-4716-95c5-373eda92d456" targetRef="sid-03d64ced-963c-4506-a5b3-21b8a9dc4279"/>
|
||||
<parallelGateway id="sid-8af65ca8-f037-4716-95c5-373eda92d456"/>
|
||||
<userTask id="sid-86ada704-a4d8-4a01-bddc-b2cd677f091d"/>
|
||||
</process>
|
||||
<bpmndi:BPMNDiagram id="BPMNDiagram_Part1_Deployment">
|
||||
<bpmndi:BPMNPlane bpmnElement="Part1_Deployment" id="BPMNPlane_Part1_Deployment">
|
||||
<bpmndi:BPMNShape id="shape-6b3bc939-03fe-47d7-b1fb-44a959045633" bpmnElement="sid-26d6e725-878e-411d-b23d-6df4ae3cbd24">
|
||||
<omgdc:Bounds x="-20.0" y="-85.0" width="30.0" height="30.0"/>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="shape-8137d303-1a5b-4a34-b8d7-995a29ae534a" bpmnElement="sid-03d64ced-963c-4506-a5b3-21b8a9dc4279">
|
||||
<omgdc:Bounds x="-20.0" y="105.00001" width="30.0" height="30.0"/>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="edge-05926a76-90de-4b3f-8fd5-d27d06dd6d6e" bpmnElement="sid-560ce1e7-a0f9-4a99-8a64-d2920292cd37">
|
||||
<omgdi:waypoint x="-5.0" y="-55.0"/>
|
||||
<omgdi:waypoint x="-95.0" y="-35.0"/>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="edge-6b52ec5d-0f90-4972-a304-022f03ccf3cf" bpmnElement="sid-da2d1cc1-7544-40f6-81ab-1d0c32c0064a">
|
||||
<omgdi:waypoint x="-5.0" y="45.0"/>
|
||||
<omgdi:waypoint x="-5.0" y="105.00001"/>
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNShape id="shape-d7a9725f-5a80-4154-a46e-229cbb12a853" bpmnElement="sid-8af65ca8-f037-4716-95c5-373eda92d456">
|
||||
<omgdc:Bounds x="-25.0" y="4.999999" width="40.0" height="40.0"/>
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="shape-03887bc6-8b53-480f-bd78-662dc1005441" bpmnElement="sid-86ada704-a4d8-4a01-bddc-b2cd677f091d">
|
||||
<omgdc:Bounds x="-195.0" y="-55.0" width="100.0" height="80.0"/>
|
||||
</bpmndi:BPMNShape>
|
||||
</bpmndi:BPMNPlane>
|
||||
</bpmndi:BPMNDiagram>
|
||||
</definitions>
|
BIN
Activiti7Demo/src/main/resources/bpmn/leave.png
Normal file
BIN
Activiti7Demo/src/main/resources/bpmn/leave.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.2 KiB |
13
Activiti7Demo/src/main/resources/bpmn/leave1.bpmn20.xml
Normal file
13
Activiti7Demo/src/main/resources/bpmn/leave1.bpmn20.xml
Normal file
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:flowable="http://flowable.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.flowable.org/processdef">
|
||||
|
||||
|
||||
</definitions>
|
@ -1,48 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<bpmn:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL"
|
||||
xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
|
||||
xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"
|
||||
xmlns:di="http://www.omg.org/spec/DD/20100524/DI"
|
||||
id="Definitions_1"
|
||||
targetNamespace="http://bpmn.io/schema/bpmn"
|
||||
exporter="bpmn-js (https://bpmn.io)"
|
||||
exporterVersion="10.3.0">
|
||||
|
||||
<bpmn:process id="Process_1" isExecutable="false">
|
||||
<bpmn:startEvent id="StartEvent_1">
|
||||
<bpmn:outgoing>SequenceFlow_1</bpmn:outgoing>
|
||||
</bpmn:startEvent>
|
||||
<bpmn:userTask id="UserTask_1" name="任务">
|
||||
<bpmn:incoming>SequenceFlow_1</bpmn:incoming>
|
||||
<bpmn:outgoing>SequenceFlow_2</bpmn:outgoing>
|
||||
</bpmn:userTask>
|
||||
<bpmn:endEvent id="EndEvent_1">
|
||||
<bpmn:incoming>SequenceFlow_2</bpmn:incoming>
|
||||
</bpmn:endEvent>
|
||||
<bpmn:sequenceFlow id="SequenceFlow_1" sourceRef="StartEvent_1" targetRef="UserTask_1" />
|
||||
<bpmn:sequenceFlow id="SequenceFlow_2" sourceRef="UserTask_1" targetRef="EndEvent_1" />
|
||||
</bpmn:process>
|
||||
|
||||
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1">
|
||||
<bpmndi:BPMNShape id="StartEvent_1_di" bpmnElement="StartEvent_1">
|
||||
<dc:Bounds x="173" y="102" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="UserTask_1_di" bpmnElement="UserTask_1">
|
||||
<dc:Bounds x="263" y="90" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="EndEvent_1_di" bpmnElement="EndEvent_1">
|
||||
<dc:Bounds x="423" y="102" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="SequenceFlow_1_di" bpmnElement="SequenceFlow_1">
|
||||
<di:waypoint x="209" y="120" />
|
||||
<di:waypoint x="263" y="120" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="SequenceFlow_2_di" bpmnElement="SequenceFlow_2">
|
||||
<di:waypoint x="363" y="120" />
|
||||
<di:waypoint x="423" y="120" />
|
||||
</bpmndi:BPMNEdge>
|
||||
</bpmndi:BPMNPlane>
|
||||
</bpmndi:BPMNDiagram>
|
||||
</bpmn:definitions>
|
@ -1,24 +1,285 @@
|
||||
package cn.whai.activiti.activiti7demo;
|
||||
|
||||
|
||||
import org.activiti.engine.ProcessEngine;
|
||||
import org.activiti.engine.ProcessEngineConfiguration;
|
||||
import org.activiti.engine.RepositoryService;
|
||||
import org.activiti.engine.*;
|
||||
import org.activiti.engine.history.HistoricProcessInstance;
|
||||
import org.activiti.engine.history.HistoricProcessInstanceQuery;
|
||||
import org.activiti.engine.repository.Deployment;
|
||||
import org.activiti.engine.repository.ProcessDefinition;
|
||||
import org.activiti.engine.runtime.ProcessInstance;
|
||||
import org.activiti.engine.task.Task;
|
||||
import org.activiti.spring.SpringProcessEngineConfiguration;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.SpringBootConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@SpringBootTest
|
||||
class Activiti7DemoApplicationTests {
|
||||
|
||||
|
||||
@Autowired
|
||||
private RepositoryService repositoryService;
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
|
||||
//进行部署
|
||||
Deployment deployment = repositoryService.createDeployment()
|
||||
.addClasspathResource("bpmn/leave.bpmn")
|
||||
.addClasspathResource("bpmn/leave.png")
|
||||
.name("请假流程")
|
||||
.deploy();
|
||||
//输出部署的一些信息
|
||||
System.out.println("流程部署ID:"+deployment.getId());
|
||||
System.out.println("流程部署名称:"+deployment.getName());
|
||||
/**
|
||||
* Opening JDBC Connection
|
||||
* ==> Preparing: insert into ACT_RE_DEPLOYMENT(ID_, NAME_, CATEGORY_, KEY_, TENANT_ID_, DEPLOY_TIME_, ENGINE_VERSION_) values(?, ?, ?, ?, ?, ?, ?)
|
||||
* ==> Parameters: b931f093-a0bf-11ef-a8d1-6ac6acfdceec(String), 请假流程(String), null, null, (String), 2024-11-12 14:31:17.803(Timestamp), null
|
||||
* <== Updates: 1
|
||||
* ==> Preparing: INSERT INTO ACT_GE_BYTEARRAY(ID_, REV_, NAME_, BYTES_, DEPLOYMENT_ID_, GENERATED_) VALUES (?, 1, ?, ?, ?, ?) , (?, 1, ?, ?, ?, ?)
|
||||
* ==> Parameters: b931f094-a0bf-11ef-a8d1-6ac6acfdceec(String), bpmn/leave.png(String), java.io.ByteArrayInputStream@3d4ea4cf(ByteArrayInputStream), b931f093-a0bf-11ef-a8d1-6ac6acfdceec(String), false(Boolean), b93217a5-a0bf-11ef-a8d1-6ac6acfdceec(String), bpmn/leave.bpmn(String), java.io.ByteArrayInputStream@655e024(ByteArrayInputStream), b931f093-a0bf-11ef-a8d1-6ac6acfdceec(String), false(Boolean)
|
||||
* <== Updates: 2
|
||||
* Closing JDBC Connection [Transaction-aware proxy for target Connection [HikariProxyConnection@1997102220 wrapping com.mysql.cj.jdbc.ConnectionImpl@4ac2b4c6]]
|
||||
* 流程部署ID:b931f093-a0bf-11ef-a8d1-6ac6acfdceec
|
||||
* 流程部署名称:请假流程
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void queryProcessDefinition() {
|
||||
|
||||
List<ProcessDefinition> processDefinitions = repositoryService.createProcessDefinitionQuery().list();
|
||||
for (ProcessDefinition processDefinition : processDefinitions) {
|
||||
System.out.println("流程定义ID:" + processDefinition.getId());
|
||||
System.out.println("流程定义名称:" + processDefinition.getName());
|
||||
System.out.println("流程定义key:" + processDefinition.getKey());
|
||||
System.out.println("流程定义版本:" + processDefinition.getVersion());
|
||||
System.out.println("流程部署ID:" + processDefinition.getDeploymentId());
|
||||
System.out.println("流程定义资源名称:" + processDefinition.getResourceName());
|
||||
System.out.println("流程定义图片资源名称:" + processDefinition.getDiagramResourceName());
|
||||
System.out.println("流程定义描述:" + processDefinition.getDescription());
|
||||
System.out.println("流程定义分类:" + processDefinition.getCategory());
|
||||
System.out.println("======================================================");
|
||||
}
|
||||
/**
|
||||
* Opening JDBC Connection
|
||||
* ==> Preparing: select distinct RES.* from ACT_RE_PROCDEF RES order by RES.ID_ asc LIMIT ? OFFSET ?
|
||||
* ==> Parameters: 2147483647(Integer), 0(Integer)
|
||||
* <== Columns: ID_, REV_, CATEGORY_, NAME_, KEY_, VERSION_, DEPLOYMENT_ID_, RESOURCE_NAME_, DGRM_RESOURCE_NAME_, DESCRIPTION_, HAS_START_FORM_KEY_, HAS_GRAPHICAL_NOTATION_, SUSPENSION_STATE_, TENANT_ID_, ENGINE_VERSION_
|
||||
* <== Row: Part1_Deployment:1:0c957bc0-a0c1-11ef-9820-6ac6acfdceec, 1, http://www.activiti.org/processdef, Part1_Deployment, Part1_Deployment, 1, 0c82b70d-a0c1-11ef-9820-6ac6acfdceec, bpmn/leave.bpmn, bpmn/leave.png, null, 0, 1, 1, , null
|
||||
* <== Total: 1
|
||||
* Closing JDBC Connection [Transaction-aware proxy for target Connection [HikariProxyConnection@1566233058 wrapping com.mysql.cj.jdbc.ConnectionImpl@17796f47]]
|
||||
* 流程定义ID:Part1_Deployment:1:0c957bc0-a0c1-11ef-9820-6ac6acfdceec
|
||||
* 流程定义名称:Part1_Deployment
|
||||
* 流程定义key:Part1_Deployment
|
||||
* 流程定义版本:1
|
||||
* 流程部署ID:0c82b70d-a0c1-11ef-9820-6ac6acfdceec
|
||||
* 流程定义资源名称:bpmn/leave.bpmn
|
||||
* 流程定义图片资源名称:bpmn/leave.png
|
||||
* 流程定义描述:null
|
||||
* 流程定义分类:http://www.activiti.org/processdef
|
||||
* ======================================================
|
||||
*/
|
||||
}
|
||||
// 流程实例
|
||||
// 流程定义(ProcessDefinition)与流程实例(ProcessInstance)是一对多关系(salvio修改)
|
||||
@Autowired
|
||||
private RuntimeService runtimeService;
|
||||
/**
|
||||
* 初始化流程实例
|
||||
*/
|
||||
@Test
|
||||
public void initProcessInstance() {
|
||||
// 流程定义KEY
|
||||
String processDefinitionKey = "Part1_Deployment";
|
||||
// 业务表KEY(用于把业务数据与Activiti7流程数据相关联)
|
||||
String businessKey = "4208169753200945";
|
||||
// 参数
|
||||
Map<String, Object> variables = new HashMap<>(16);
|
||||
ProcessInstance processInstance = this.runtimeService
|
||||
.startProcessInstanceByKey(processDefinitionKey, businessKey, variables);
|
||||
System.out.println("流程实例ID:" + processInstance.getProcessInstanceId());
|
||||
/**
|
||||
* Opening JDBC Connection
|
||||
* ==> Preparing: select * from ACT_RE_PROCDEF where KEY_ = ? and (TENANT_ID_ = '' or TENANT_ID_ is null) and VERSION_ = (select max(VERSION_) from ACT_RE_PROCDEF where KEY_ = ? and (TENANT_ID_ = '' or TENANT_ID_ is null))
|
||||
* ==> Parameters: Part1_Deployment(String), Part1_Deployment(String)
|
||||
* <== Columns: ID_, REV_, CATEGORY_, NAME_, KEY_, VERSION_, DEPLOYMENT_ID_, RESOURCE_NAME_, DGRM_RESOURCE_NAME_, DESCRIPTION_, HAS_START_FORM_KEY_, HAS_GRAPHICAL_NOTATION_, SUSPENSION_STATE_, TENANT_ID_, ENGINE_VERSION_
|
||||
* <== Row: Part1_Deployment:1:0c957bc0-a0c1-11ef-9820-6ac6acfdceec, 1, http://www.activiti.org/processdef, Part1_Deployment, Part1_Deployment, 1, 0c82b70d-a0c1-11ef-9820-6ac6acfdceec, bpmn/leave.bpmn, bpmn/leave.png, null, 0, 1, 1, , null
|
||||
* <== Total: 1
|
||||
* ==> Preparing: select * from ACT_RU_VARIABLE where TASK_ID_ = ?
|
||||
* ==> Parameters: b25c87dd-a0c3-11ef-8ba8-68c6acfdcef0(String)
|
||||
* <== Total: 0
|
||||
* ==> Preparing: insert into ACT_HI_TASKINST ( ID_, PROC_DEF_ID_, PROC_INST_ID_, EXECUTION_ID_, NAME_, PARENT_TASK_ID_, DESCRIPTION_, OWNER_, ASSIGNEE_, START_TIME_, CLAIM_TIME_, END_TIME_, DURATION_, DELETE_REASON_, TASK_DEF_KEY_, FORM_KEY_, PRIORITY_, DUE_DATE_, CATEGORY_, TENANT_ID_ ) values ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )
|
||||
* ==> Parameters: b25c87dd-a0c3-11ef-8ba8-68c6acfdcef0(String), Part1_Deployment:1:0c957bc0-a0c1-11ef-9820-6ac6acfdceec(String), b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0(String), b25ab31a-a0c3-11ef-8ba8-68c6acfdcef0(String), UserTask(String), null, null, null, admin(String), 2024-11-12 14:59:44.325(Timestamp), null, null, null, null, sid-192966db-031d-4a50-886d-379935dd9bc1(String), null, 50(Integer), null, null, (String)
|
||||
* <== Updates: 1
|
||||
* ==> Preparing: insert into ACT_HI_PROCINST ( ID_, PROC_INST_ID_, BUSINESS_KEY_, PROC_DEF_ID_, START_TIME_, END_TIME_, DURATION_, START_USER_ID_, START_ACT_ID_, END_ACT_ID_, SUPER_PROCESS_INSTANCE_ID_, DELETE_REASON_, TENANT_ID_, NAME_ ) values ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )
|
||||
* ==> Parameters: b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0(String), b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0(String), 4208169753200945(String), Part1_Deployment:1:0c957bc0-a0c1-11ef-9820-6ac6acfdceec(String), 2024-11-12 14:59:44.311(Timestamp), null, null, null, sid-26d6e725-878e-411d-b23d-6df4ae3cbd24(String), null, null, null, (String), null
|
||||
* <== Updates: 1
|
||||
* ==> Preparing: insert into ACT_HI_ACTINST ( ID_, PROC_DEF_ID_, PROC_INST_ID_, EXECUTION_ID_, ACT_ID_, TASK_ID_, CALL_PROC_INST_ID_, ACT_NAME_, ACT_TYPE_, ASSIGNEE_, START_TIME_, END_TIME_, DURATION_, DELETE_REASON_, TENANT_ID_ ) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) , (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
* ==> Parameters: b25ada2b-a0c3-11ef-8ba8-68c6acfdcef0(String), Part1_Deployment:1:0c957bc0-a0c1-11ef-9820-6ac6acfdceec(String), b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0(String), b25ab31a-a0c3-11ef-8ba8-68c6acfdcef0(String), sid-26d6e725-878e-411d-b23d-6df4ae3cbd24(String), null, null, null, startEvent(String), null, 2024-11-12 14:59:44.314(Timestamp), 2024-11-12 14:59:44.316(Timestamp), 2(Long), null, (String), b25b4f5c-a0c3-11ef-8ba8-68c6acfdcef0(String), Part1_Deployment:1:0c957bc0-a0c1-11ef-9820-6ac6acfdceec(String), b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0(String), b25ab31a-a0c3-11ef-8ba8-68c6acfdcef0(String), sid-192966db-031d-4a50-886d-379935dd9bc1(String), b25c87dd-a0c3-11ef-8ba8-68c6acfdcef0(String), null, UserTask(String), userTask(String), admin(String), 2024-11-12 14:59:44.317(Timestamp), null, null, null, (String)
|
||||
* <== Updates: 2
|
||||
* ==> Preparing: insert into ACT_HI_IDENTITYLINK (ID_, TYPE_, USER_ID_, GROUP_ID_, TASK_ID_, PROC_INST_ID_) values (?, ?, ?, ?, ?, ?)
|
||||
* ==> Parameters: b25cd5fe-a0c3-11ef-8ba8-68c6acfdcef0(String), participant(String), admin(String), null, null, b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0(String)
|
||||
* <== Updates: 1
|
||||
* ==> Preparing: insert into ACT_RU_EXECUTION (ID_, REV_, PROC_INST_ID_, BUSINESS_KEY_, PROC_DEF_ID_, ACT_ID_, IS_ACTIVE_, IS_CONCURRENT_, IS_SCOPE_,IS_EVENT_SCOPE_, IS_MI_ROOT_, PARENT_ID_, SUPER_EXEC_, ROOT_PROC_INST_ID_, SUSPENSION_STATE_, TENANT_ID_, NAME_, START_TIME_, START_USER_ID_, IS_COUNT_ENABLED_, EVT_SUBSCR_COUNT_, TASK_COUNT_, JOB_COUNT_, TIMER_JOB_COUNT_, SUSP_JOB_COUNT_, DEADLETTER_JOB_COUNT_, VAR_COUNT_, ID_LINK_COUNT_) values (?, 1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) , (?, 1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
* ==> Parameters: b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0(String), b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0(String), 4208169753200945(String), Part1_Deployment:1:0c957bc0-a0c1-11ef-9820-6ac6acfdceec(String), null, true(Boolean), false(Boolean), true(Boolean), false(Boolean), false(Boolean), null, null, b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0(String), 1(Integer), (String), null, 2024-11-12 14:59:44.311(Timestamp), null, false(Boolean), 0(Integer), 0(Integer), 0(Integer), 0(Integer), 0(Integer), 0(Integer), 0(Integer), 0(Integer), b25ab31a-a0c3-11ef-8ba8-68c6acfdcef0(String), b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0(String), null, Part1_Deployment:1:0c957bc0-a0c1-11ef-9820-6ac6acfdceec(String), sid-192966db-031d-4a50-886d-379935dd9bc1(String), true(Boolean), false(Boolean), false(Boolean), false(Boolean), false(Boolean), b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0(String), null, b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0(String), 1(Integer), (String), null, 2024-11-12 14:59:44.313(Timestamp), null, false(Boolean), 0(Integer), 0(Integer), 0(Integer), 0(Integer), 0(Integer), 0(Integer), 0(Integer), 0(Integer)
|
||||
* <== Updates: 2
|
||||
* ==> Preparing: insert into ACT_RU_TASK (ID_, REV_, NAME_, PARENT_TASK_ID_, DESCRIPTION_, PRIORITY_, CREATE_TIME_, OWNER_, ASSIGNEE_, DELEGATION_, EXECUTION_ID_, PROC_INST_ID_, PROC_DEF_ID_, TASK_DEF_KEY_, DUE_DATE_, CATEGORY_, SUSPENSION_STATE_, TENANT_ID_, FORM_KEY_, CLAIM_TIME_) values (?, 1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )
|
||||
* ==> Parameters: b25c87dd-a0c3-11ef-8ba8-68c6acfdcef0(String), UserTask(String), null, null, 50(Integer), 2024-11-12 14:59:44.317(Timestamp), null, admin(String), null, b25ab31a-a0c3-11ef-8ba8-68c6acfdcef0(String), b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0(String), Part1_Deployment:1:0c957bc0-a0c1-11ef-9820-6ac6acfdceec(String), sid-192966db-031d-4a50-886d-379935dd9bc1(String), null, null, 1(Integer), (String), null, null
|
||||
* <== Updates: 1
|
||||
* ==> Preparing: insert into ACT_RU_IDENTITYLINK (ID_, REV_, TYPE_, USER_ID_, GROUP_ID_, TASK_ID_, PROC_INST_ID_, PROC_DEF_ID_) values (?, 1, ?, ?, ?, ?, ?, ?)
|
||||
* ==> Parameters: b25cd5fe-a0c3-11ef-8ba8-68c6acfdcef0(String), participant(String), admin(String), null, null, b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0(String), null
|
||||
* <== Updates: 1
|
||||
* Closing JDBC Connection [Transaction-aware proxy for target Connection [HikariProxyConnection@621103114 wrapping com.mysql.cj.jdbc.ConnectionImpl@4ac2b4c6]]
|
||||
* 流程实例ID:b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询流程实例
|
||||
*/
|
||||
@Test
|
||||
public void getProcessInstance() {
|
||||
String processInstanceId = "b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0";
|
||||
ProcessInstance processInstance = this.runtimeService.createProcessInstanceQuery()
|
||||
.processInstanceId(processInstanceId)
|
||||
.singleResult();
|
||||
System.out.println("ProcessInstanceId:" + processInstance.getProcessInstanceId());
|
||||
System.out.println("ProcessDefinitionId:" + processInstance.getProcessDefinitionId());
|
||||
System.out.println("isEnded:" + processInstance.isEnded());
|
||||
System.out.println("isSuspended:" + processInstance.isSuspended());
|
||||
/**
|
||||
* Opening JDBC Connection
|
||||
* ==> Preparing: select distinct RES.* , P.KEY_ as ProcessDefinitionKey, P.ID_ as ProcessDefinitionId, P.NAME_ as ProcessDefinitionName, P.VERSION_ as ProcessDefinitionVersion, P.DEPLOYMENT_ID_ as DeploymentId, S.PROC_INST_ID_ AS PARENT_PROC_INST_ID_ from ACT_RU_EXECUTION RES inner join ACT_RE_PROCDEF P on RES.PROC_DEF_ID_ = P.ID_ left outer join ACT_RU_EXECUTION S on RES.SUPER_EXEC_ = S.ID_ WHERE RES.PARENT_ID_ is null and RES.ID_ = ? and RES.PROC_INST_ID_ = ? order by RES.ID_ asc LIMIT ? OFFSET ?
|
||||
* ==> Parameters: b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0(String), b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0(String), 2147483647(Integer), 0(Integer)
|
||||
* <== Columns: ID_, REV_, PROC_INST_ID_, BUSINESS_KEY_, PARENT_ID_, PROC_DEF_ID_, SUPER_EXEC_, ROOT_PROC_INST_ID_, ACT_ID_, IS_ACTIVE_, IS_CONCURRENT_, IS_SCOPE_, IS_EVENT_SCOPE_, IS_MI_ROOT_, SUSPENSION_STATE_, CACHED_ENT_STATE_, TENANT_ID_, NAME_, START_TIME_, START_USER_ID_, LOCK_TIME_, IS_COUNT_ENABLED_, EVT_SUBSCR_COUNT_, TASK_COUNT_, JOB_COUNT_, TIMER_JOB_COUNT_, SUSP_JOB_COUNT_, DEADLETTER_JOB_COUNT_, VAR_COUNT_, ID_LINK_COUNT_, ProcessDefinitionKey, ProcessDefinitionId, ProcessDefinitionName, ProcessDefinitionVersion, DeploymentId, PARENT_PROC_INST_ID_
|
||||
* <== Row: b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0, 1, b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0, 4208169753200945, null, Part1_Deployment:1:0c957bc0-a0c1-11ef-9820-6ac6acfdceec, null, b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0, null, 1, 0, 1, 0, 0, 1, null, , null, 2024-11-12 14:59:44.311, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, Part1_Deployment, Part1_Deployment:1:0c957bc0-a0c1-11ef-9820-6ac6acfdceec, Part1_Deployment, 1, 0c82b70d-a0c1-11ef-9820-6ac6acfdceec, null
|
||||
* <== Total: 1
|
||||
* Closing JDBC Connection [Transaction-aware proxy for target Connection [HikariProxyConnection@1118158255 wrapping com.mysql.cj.jdbc.ConnectionImpl@77eb0e47]]
|
||||
* ProcessInstanceId:b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0
|
||||
* ProcessDefinitionId:Part1_Deployment:1:0c957bc0-a0c1-11ef-9820-6ac6acfdceec
|
||||
* isEnded:false
|
||||
* isSuspended:false
|
||||
*/
|
||||
|
||||
// 查询流程实例列表
|
||||
List<ProcessInstance> processInstanceList = this.runtimeService.createProcessInstanceQuery().list();
|
||||
if (!CollectionUtils.isEmpty(processInstanceList)) {
|
||||
processInstanceList.forEach(pi -> {
|
||||
System.out.println("ProcessInstanceId:" + pi.getProcessInstanceId());
|
||||
System.out.println("ProcessDefinitionId:" + pi.getProcessDefinitionId());
|
||||
System.out.println("isEnded:" + pi.isEnded());
|
||||
System.out.println("isSuspended:" + pi.isSuspended());
|
||||
});
|
||||
}
|
||||
// 挂起流程实例
|
||||
this.runtimeService.suspendProcessInstanceById(processInstanceId);
|
||||
// 激活流程实例
|
||||
this.runtimeService.activateProcessInstanceById(processInstanceId);
|
||||
// 删除流程实例
|
||||
this.runtimeService.deleteProcessInstance(processInstanceId, "测试删除流程实例");
|
||||
}
|
||||
|
||||
/**
|
||||
* 任务管理
|
||||
*/
|
||||
@Autowired
|
||||
private TaskService taskService;
|
||||
|
||||
/**
|
||||
* 查询任务列表
|
||||
*/
|
||||
@Test
|
||||
public void listTasks() {
|
||||
List<Task> taskList = this.taskService.createTaskQuery().list();
|
||||
if (!CollectionUtils.isEmpty(taskList)) {
|
||||
taskList.forEach(task -> {
|
||||
System.out.println("Id:" + task.getId());
|
||||
System.out.println("Name:" + task.getName());
|
||||
System.out.println("Assignee:" + task.getAssignee());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void listTasksByAssignee() {
|
||||
/**
|
||||
* 查询Admin的代办任务
|
||||
*/
|
||||
String assignee = "admin";
|
||||
List<Task> taskList = this.taskService.createTaskQuery()
|
||||
.taskAssignee(assignee)
|
||||
.list();
|
||||
if (!CollectionUtils.isEmpty(taskList)) {
|
||||
taskList.forEach(task -> {
|
||||
System.out.println("Id:" + task.getId());
|
||||
System.out.println("Name:" + task.getName());
|
||||
System.out.println("Assignee:" + task.getAssignee());
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// 完成任务
|
||||
String taskId = "354b9d90-477f-11ed-abfa-e4a8dfd43d4a";
|
||||
Map<String, Object> variables = new HashMap<>(16);
|
||||
this.taskService.complete(taskId, variables);
|
||||
|
||||
|
||||
// 给定用户成为任务的受理人。
|
||||
String userId = "jason";
|
||||
taskService.claim(taskId, userId);
|
||||
|
||||
// 归还任务,分配的任务回收,撤回
|
||||
taskService.unclaim(taskId);
|
||||
|
||||
// 将给定任务的被分派人更改为给定的 userId。不检查身份组件是否知道该用户。
|
||||
taskService.setAssignee(taskId, userId);
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private HistoryService historyService;
|
||||
|
||||
// 历史记录
|
||||
@Test
|
||||
public void history() {
|
||||
// 查询历史流程实例
|
||||
HistoricProcessInstanceQuery historicProcessInstanceQuery =
|
||||
this.historyService
|
||||
.createHistoricProcessInstanceQuery()
|
||||
.orderByProcessInstanceEndTime();
|
||||
List<HistoricProcessInstance> list = historicProcessInstanceQuery.list();
|
||||
|
||||
list.forEach(historicProcessInstance -> {
|
||||
System.out.println("ProcessInstanceId:" + historicProcessInstance.getId());
|
||||
System.out.println("ProcessDefinitionId:" + historicProcessInstance.getProcessDefinitionId());
|
||||
});
|
||||
|
||||
|
||||
|
||||
// 根据流程实例ID查询历史
|
||||
String processInstanceId = "0f8a9b00-479e-11ed-af85-e4a8dfd43d4a";
|
||||
List<HistoricProcessInstance> historicProcessInstances =
|
||||
this.historyService
|
||||
.createHistoricProcessInstanceQuery()
|
||||
.processInstanceId(processInstanceId)
|
||||
.list();
|
||||
historicProcessInstances.forEach(historicProcessInstance -> {
|
||||
System.out.println("ProcessInstanceId:" + historicProcessInstance.getId());
|
||||
System.out.println("ProcessDefinitionId:" + historicProcessInstance.getProcessDefinitionId());
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -55,3 +55,225 @@ BPMN(Business Process Model And Notation),业务流程模型和符号,
|
||||
- mysql
|
||||
|
||||
- 在Navicat工具中创建`activiti`的数据库,用于后续的实验.
|
||||
|
||||
|
||||
|
||||
### Activiti使用步骤
|
||||
|
||||
> 2.4.1 整合Activiti
|
||||
> Activiti是一个工作流引擎,业务系统使用Activiti来对系统的业务流程进行自动化管理,为了方便业务系统访问(操作)Activiti的接口或功能,通常将Activiti和业务系统的环境集成在一起。
|
||||
> 2.4.2 业务流程建模
|
||||
> 使用Activiti流程建模工具(Activity-designer)定义业务流程(.bpmn文件)。
|
||||
> .bpmn文件就是业务流程定义文件,通过xml定义业务流程。
|
||||
> 如果使用其他公司开发的工作引擎一般都提供了可视化的建模工具(Process Designer)用于生成流程定义文件,建模工具操作直观,一般都支持图形化拖拽方式、多窗口的用户界面、丰富的过程图形元素、过程元素拷贝、粘贴、删除等功能。
|
||||
> 2.4.3 部署业务流程
|
||||
> 向Activiti部署业务流程定义(.bpmn文件)。
|
||||
> 使用Activiti提供的API向Activiti中部署.bpmn文件(一般情况下还需要一起部署业务流程的图片.png)。
|
||||
> 2.4.4 启动流程实例
|
||||
> 启动一个流程实例表示开始一次业务流程的运行,比如员工请假流程部署完成,如果张三要请假就可以启动一个流程实例,如果李四要请假也需要启动一个流程实例,两个流程的执行互不影响,就好比定义一个Java类,实例化两个Java对象一样,部署的流程就好比Java类,启动一个流程实例就好比new一个Java对象。
|
||||
> 2.4.5 查询待办任务
|
||||
> 因为现在系统的业务流程已经交给Activiti管理,通过Activiti就可以查询当前流程执行到哪里了,当前用户需要办理什么任务了,这些Activiti帮我们管理了,而不像传统方式中需要我们在SQL语句中的WHERE条件中指定当前查询的状态值是多少。
|
||||
> 2.4.6 处理待办任务
|
||||
> 用户查询待办任务后,就可以办理某个任务,如果这任务办理完成还需要其他用户办理,比如采购单创建后由部门经理审核,这个过程也是由Activiti帮我们完成了,不需要我们在代码中硬编码指定下一个任务办理人了
|
||||
> 2.4.7 结束流程
|
||||
> 当任务办理完成没有下一个任务/结点了,这个流程实例就完成了。
|
||||
|
||||
### Service总览
|
||||
|
||||
![img](http://42.192.130.83:9000/picgo/imgs/v2-c33ee3444141b1a2c3b45ef88db771df_1440w.jpg_repeat_1731401329594__239673.png)
|
||||
|
||||
- RepositoryService Activiti的资源管理接口:管理和控制流程发布包和流程定义的操作
|
||||
- RuntimeService Activiti的流程运行管理接口:流程执行相关的信息
|
||||
- TaskService Activiti的任务管理接口:
|
||||
- HistoryService Activiti的历史管理接口
|
||||
- ManagementService Activiti的引擎管理接口,管理和维护功能
|
||||
|
||||
#### 数据表解读
|
||||
|
||||
Activiti 使用到的表都是 ACT_ 开头的,表名的第二部分表示用途。
|
||||
|
||||
##### ACT_GE_ (GE) 表示 general 全局通用数据及设置,各种情况都使用的数据。
|
||||
|
||||
> #### 全局通用数据(ACT_GE_*)
|
||||
>
|
||||
> | ACT_GE_BYTEARRAY | 二进制数据表,存储通用的流程定义和流程资源。 |
|
||||
> | ---------------- | ---------------------------------------------------- |
|
||||
> | ACT_GE_PROPERTY | 系统相关属性,属性数据表存储整个流程引擎级别的数据。 |
|
||||
|
||||
##### ACT_HI_ (HI) 表示 history 历史数据表,包含着程执行的历史相关数据。
|
||||
|
||||
##### ACT_RE_ (RE) 表示 repository 存储,包含的是静态信息。
|
||||
|
||||
##### ACT_RU_ (RU) 表示 runtime 运行时,运行时的流程变量,用户任务,变量,职责(job)等运行时数据。Activiti 只存储实例执行期间的运行时数据,当流程实例结束时,将删除这些记录 (salvio修
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## 流程定义 ProcessDefinition
|
||||
|
||||
```java
|
||||
@Autowired
|
||||
private RepositoryService repositoryService;
|
||||
@Test
|
||||
void queryProcessDe() {
|
||||
List<ProcessDefinition> processDefinitions = repositoryService.createProcessDefinitionQuery().list();
|
||||
for (ProcessDefinition processDefinition : processDefinitions) {
|
||||
System.out.println("流程定义ID:" + processDefinition.getId());
|
||||
System.out.println("流程定义名称:" + processDefinition.getName());
|
||||
System.out.println("流程定义key:" + processDefinition.getKey());
|
||||
System.out.println("流程定义版本:" + processDefinition.getVersion());
|
||||
System.out.println("流程部署ID:" + processDefinition.getDeploymentId());
|
||||
System.out.println("流程定义资源名称:" + processDefinition.getResourceName());
|
||||
System.out.println("流程定义图片资源名称:" + processDefinition.getDiagramResourceName());
|
||||
System.out.println("流程定义描述:" + processDefinition.getDescription());
|
||||
System.out.println("流程定义分类:" + processDefinition.getCategory());
|
||||
System.out.println("======================================================");
|
||||
}
|
||||
/**
|
||||
* Opening JDBC Connection
|
||||
* ==> Preparing: select distinct RES.* from ACT_RE_PROCDEF RES order by RES.ID_ asc LIMIT ? OFFSET ?
|
||||
* ==> Parameters: 2147483647(Integer), 0(Integer)
|
||||
* <== Columns: ID_, REV_, CATEGORY_, NAME_, KEY_, VERSION_, DEPLOYMENT_ID_, RESOURCE_NAME_, DGRM_RESOURCE_NAME_, DESCRIPTION_, HAS_START_FORM_KEY_, HAS_GRAPHICAL_NOTATION_, SUSPENSION_STATE_, TENANT_ID_, ENGINE_VERSION_
|
||||
* <== Row: Part1_Deployment:1:0c957bc0-a0c1-11ef-9820-6ac6acfdceec, 1, http://www.activiti.org/processdef, Part1_Deployment, Part1_Deployment, 1, 0c82b70d-a0c1-11ef-9820-6ac6acfdceec, bpmn/leave.bpmn, bpmn/leave.png, null, 0, 1, 1, , null
|
||||
* <== Total: 1
|
||||
* Closing JDBC Connection [Transaction-aware proxy for target Connection [HikariProxyConnection@1566233058 wrapping com.mysql.cj.jdbc.ConnectionImpl@17796f47]]
|
||||
* 流程定义ID:Part1_Deployment:1:0c957bc0-a0c1-11ef-9820-6ac6acfdceec
|
||||
* 流程定义名称:Part1_Deployment
|
||||
* 流程定义key:Part1_Deployment
|
||||
* 流程定义版本:1
|
||||
* 流程部署ID:0c82b70d-a0c1-11ef-9820-6ac6acfdceec
|
||||
* 流程定义资源名称:bpmn/leave.bpmn
|
||||
* 流程定义图片资源名称:bpmn/leave.png
|
||||
* 流程定义描述:null
|
||||
* 流程定义分类:http://www.activiti.org/processdef
|
||||
* ======================================================
|
||||
*/
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
## 流程实例 ProcessInstance
|
||||
|
||||
|
||||
|
||||
```java
|
||||
/**
|
||||
* 初始化流程实例
|
||||
*/
|
||||
@Test
|
||||
public void initProcessInstance() {
|
||||
// 流程定义KEY
|
||||
String processDefinitionKey = "Part1_Deployment";
|
||||
// 业务表KEY(用于把业务数据与Activiti7流程数据相关联)
|
||||
String businessKey = "4208169753200945";
|
||||
// 参数
|
||||
Map<String, Object> variables = new HashMap<>(16);
|
||||
ProcessInstance processInstance = this.runtimeService
|
||||
.startProcessInstanceByKey(processDefinitionKey, businessKey, variables);
|
||||
System.out.println("流程实例ID:" + processInstance.getProcessInstanceId());
|
||||
/**
|
||||
* Opening JDBC Connection
|
||||
* ==> Preparing: select * from ACT_RE_PROCDEF where KEY_ = ? and (TENANT_ID_ = '' or TENANT_ID_ is null) and VERSION_ = (select max(VERSION_) from ACT_RE_PROCDEF where KEY_ = ? and (TENANT_ID_ = '' or TENANT_ID_ is null))
|
||||
* ==> Parameters: Part1_Deployment(String), Part1_Deployment(String)
|
||||
* <== Columns: ID_, REV_, CATEGORY_, NAME_, KEY_, VERSION_, DEPLOYMENT_ID_, RESOURCE_NAME_, DGRM_RESOURCE_NAME_, DESCRIPTION_, HAS_START_FORM_KEY_, HAS_GRAPHICAL_NOTATION_, SUSPENSION_STATE_, TENANT_ID_, ENGINE_VERSION_
|
||||
* <== Row: Part1_Deployment:1:0c957bc0-a0c1-11ef-9820-6ac6acfdceec, 1, http://www.activiti.org/processdef, Part1_Deployment, Part1_Deployment, 1, 0c82b70d-a0c1-11ef-9820-6ac6acfdceec, bpmn/leave.bpmn, bpmn/leave.png, null, 0, 1, 1, , null
|
||||
* <== Total: 1
|
||||
* ==> Preparing: select * from ACT_RU_VARIABLE where TASK_ID_ = ?
|
||||
* ==> Parameters: b25c87dd-a0c3-11ef-8ba8-68c6acfdcef0(String)
|
||||
* <== Total: 0
|
||||
* ==> Preparing: insert into ACT_HI_TASKINST ( ID_, PROC_DEF_ID_, PROC_INST_ID_, EXECUTION_ID_, NAME_, PARENT_TASK_ID_, DESCRIPTION_, OWNER_, ASSIGNEE_, START_TIME_, CLAIM_TIME_, END_TIME_, DURATION_, DELETE_REASON_, TASK_DEF_KEY_, FORM_KEY_, PRIORITY_, DUE_DATE_, CATEGORY_, TENANT_ID_ ) values ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )
|
||||
* ==> Parameters: b25c87dd-a0c3-11ef-8ba8-68c6acfdcef0(String), Part1_Deployment:1:0c957bc0-a0c1-11ef-9820-6ac6acfdceec(String), b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0(String), b25ab31a-a0c3-11ef-8ba8-68c6acfdcef0(String), UserTask(String), null, null, null, admin(String), 2024-11-12 14:59:44.325(Timestamp), null, null, null, null, sid-192966db-031d-4a50-886d-379935dd9bc1(String), null, 50(Integer), null, null, (String)
|
||||
* <== Updates: 1
|
||||
* ==> Preparing: insert into ACT_HI_PROCINST ( ID_, PROC_INST_ID_, BUSINESS_KEY_, PROC_DEF_ID_, START_TIME_, END_TIME_, DURATION_, START_USER_ID_, START_ACT_ID_, END_ACT_ID_, SUPER_PROCESS_INSTANCE_ID_, DELETE_REASON_, TENANT_ID_, NAME_ ) values ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )
|
||||
* ==> Parameters: b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0(String), b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0(String), 4208169753200945(String), Part1_Deployment:1:0c957bc0-a0c1-11ef-9820-6ac6acfdceec(String), 2024-11-12 14:59:44.311(Timestamp), null, null, null, sid-26d6e725-878e-411d-b23d-6df4ae3cbd24(String), null, null, null, (String), null
|
||||
* <== Updates: 1
|
||||
* ==> Preparing: insert into ACT_HI_ACTINST ( ID_, PROC_DEF_ID_, PROC_INST_ID_, EXECUTION_ID_, ACT_ID_, TASK_ID_, CALL_PROC_INST_ID_, ACT_NAME_, ACT_TYPE_, ASSIGNEE_, START_TIME_, END_TIME_, DURATION_, DELETE_REASON_, TENANT_ID_ ) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) , (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
* ==> Parameters: b25ada2b-a0c3-11ef-8ba8-68c6acfdcef0(String), Part1_Deployment:1:0c957bc0-a0c1-11ef-9820-6ac6acfdceec(String), b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0(String), b25ab31a-a0c3-11ef-8ba8-68c6acfdcef0(String), sid-26d6e725-878e-411d-b23d-6df4ae3cbd24(String), null, null, null, startEvent(String), null, 2024-11-12 14:59:44.314(Timestamp), 2024-11-12 14:59:44.316(Timestamp), 2(Long), null, (String), b25b4f5c-a0c3-11ef-8ba8-68c6acfdcef0(String), Part1_Deployment:1:0c957bc0-a0c1-11ef-9820-6ac6acfdceec(String), b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0(String), b25ab31a-a0c3-11ef-8ba8-68c6acfdcef0(String), sid-192966db-031d-4a50-886d-379935dd9bc1(String), b25c87dd-a0c3-11ef-8ba8-68c6acfdcef0(String), null, UserTask(String), userTask(String), admin(String), 2024-11-12 14:59:44.317(Timestamp), null, null, null, (String)
|
||||
* <== Updates: 2
|
||||
* ==> Preparing: insert into ACT_HI_IDENTITYLINK (ID_, TYPE_, USER_ID_, GROUP_ID_, TASK_ID_, PROC_INST_ID_) values (?, ?, ?, ?, ?, ?)
|
||||
* ==> Parameters: b25cd5fe-a0c3-11ef-8ba8-68c6acfdcef0(String), participant(String), admin(String), null, null, b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0(String)
|
||||
* <== Updates: 1
|
||||
* ==> Preparing: insert into ACT_RU_EXECUTION (ID_, REV_, PROC_INST_ID_, BUSINESS_KEY_, PROC_DEF_ID_, ACT_ID_, IS_ACTIVE_, IS_CONCURRENT_, IS_SCOPE_,IS_EVENT_SCOPE_, IS_MI_ROOT_, PARENT_ID_, SUPER_EXEC_, ROOT_PROC_INST_ID_, SUSPENSION_STATE_, TENANT_ID_, NAME_, START_TIME_, START_USER_ID_, IS_COUNT_ENABLED_, EVT_SUBSCR_COUNT_, TASK_COUNT_, JOB_COUNT_, TIMER_JOB_COUNT_, SUSP_JOB_COUNT_, DEADLETTER_JOB_COUNT_, VAR_COUNT_, ID_LINK_COUNT_) values (?, 1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) , (?, 1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
* ==> Parameters: b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0(String), b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0(String), 4208169753200945(String), Part1_Deployment:1:0c957bc0-a0c1-11ef-9820-6ac6acfdceec(String), null, true(Boolean), false(Boolean), true(Boolean), false(Boolean), false(Boolean), null, null, b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0(String), 1(Integer), (String), null, 2024-11-12 14:59:44.311(Timestamp), null, false(Boolean), 0(Integer), 0(Integer), 0(Integer), 0(Integer), 0(Integer), 0(Integer), 0(Integer), 0(Integer), b25ab31a-a0c3-11ef-8ba8-68c6acfdcef0(String), b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0(String), null, Part1_Deployment:1:0c957bc0-a0c1-11ef-9820-6ac6acfdceec(String), sid-192966db-031d-4a50-886d-379935dd9bc1(String), true(Boolean), false(Boolean), false(Boolean), false(Boolean), false(Boolean), b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0(String), null, b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0(String), 1(Integer), (String), null, 2024-11-12 14:59:44.313(Timestamp), null, false(Boolean), 0(Integer), 0(Integer), 0(Integer), 0(Integer), 0(Integer), 0(Integer), 0(Integer), 0(Integer)
|
||||
* <== Updates: 2
|
||||
* ==> Preparing: insert into ACT_RU_TASK (ID_, REV_, NAME_, PARENT_TASK_ID_, DESCRIPTION_, PRIORITY_, CREATE_TIME_, OWNER_, ASSIGNEE_, DELEGATION_, EXECUTION_ID_, PROC_INST_ID_, PROC_DEF_ID_, TASK_DEF_KEY_, DUE_DATE_, CATEGORY_, SUSPENSION_STATE_, TENANT_ID_, FORM_KEY_, CLAIM_TIME_) values (?, 1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )
|
||||
* ==> Parameters: b25c87dd-a0c3-11ef-8ba8-68c6acfdcef0(String), UserTask(String), null, null, 50(Integer), 2024-11-12 14:59:44.317(Timestamp), null, admin(String), null, b25ab31a-a0c3-11ef-8ba8-68c6acfdcef0(String), b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0(String), Part1_Deployment:1:0c957bc0-a0c1-11ef-9820-6ac6acfdceec(String), sid-192966db-031d-4a50-886d-379935dd9bc1(String), null, null, 1(Integer), (String), null, null
|
||||
* <== Updates: 1
|
||||
* ==> Preparing: insert into ACT_RU_IDENTITYLINK (ID_, REV_, TYPE_, USER_ID_, GROUP_ID_, TASK_ID_, PROC_INST_ID_, PROC_DEF_ID_) values (?, 1, ?, ?, ?, ?, ?, ?)
|
||||
* ==> Parameters: b25cd5fe-a0c3-11ef-8ba8-68c6acfdcef0(String), participant(String), admin(String), null, null, b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0(String), null
|
||||
* <== Updates: 1
|
||||
* Closing JDBC Connection [Transaction-aware proxy for target Connection [HikariProxyConnection@621103114 wrapping com.mysql.cj.jdbc.ConnectionImpl@4ac2b4c6]]
|
||||
* 流程实例ID:b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询流程实例
|
||||
*/
|
||||
@Test
|
||||
public void getProcessInstance() {
|
||||
String processInstanceId = "b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0";
|
||||
ProcessInstance processInstance = this.runtimeService.createProcessInstanceQuery()
|
||||
.processInstanceId(processInstanceId)
|
||||
.singleResult();
|
||||
System.out.println("ProcessInstanceId:" + processInstance.getProcessInstanceId());
|
||||
System.out.println("ProcessDefinitionId:" + processInstance.getProcessDefinitionId());
|
||||
System.out.println("isEnded:" + processInstance.isEnded());
|
||||
System.out.println("isSuspended:" + processInstance.isSuspended());
|
||||
/**
|
||||
* Opening JDBC Connection
|
||||
* ==> Preparing: select distinct RES.* , P.KEY_ as ProcessDefinitionKey, P.ID_ as ProcessDefinitionId, P.NAME_ as ProcessDefinitionName, P.VERSION_ as ProcessDefinitionVersion, P.DEPLOYMENT_ID_ as DeploymentId, S.PROC_INST_ID_ AS PARENT_PROC_INST_ID_ from ACT_RU_EXECUTION RES inner join ACT_RE_PROCDEF P on RES.PROC_DEF_ID_ = P.ID_ left outer join ACT_RU_EXECUTION S on RES.SUPER_EXEC_ = S.ID_ WHERE RES.PARENT_ID_ is null and RES.ID_ = ? and RES.PROC_INST_ID_ = ? order by RES.ID_ asc LIMIT ? OFFSET ?
|
||||
* ==> Parameters: b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0(String), b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0(String), 2147483647(Integer), 0(Integer)
|
||||
* <== Columns: ID_, REV_, PROC_INST_ID_, BUSINESS_KEY_, PARENT_ID_, PROC_DEF_ID_, SUPER_EXEC_, ROOT_PROC_INST_ID_, ACT_ID_, IS_ACTIVE_, IS_CONCURRENT_, IS_SCOPE_, IS_EVENT_SCOPE_, IS_MI_ROOT_, SUSPENSION_STATE_, CACHED_ENT_STATE_, TENANT_ID_, NAME_, START_TIME_, START_USER_ID_, LOCK_TIME_, IS_COUNT_ENABLED_, EVT_SUBSCR_COUNT_, TASK_COUNT_, JOB_COUNT_, TIMER_JOB_COUNT_, SUSP_JOB_COUNT_, DEADLETTER_JOB_COUNT_, VAR_COUNT_, ID_LINK_COUNT_, ProcessDefinitionKey, ProcessDefinitionId, ProcessDefinitionName, ProcessDefinitionVersion, DeploymentId, PARENT_PROC_INST_ID_
|
||||
* <== Row: b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0, 1, b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0, 4208169753200945, null, Part1_Deployment:1:0c957bc0-a0c1-11ef-9820-6ac6acfdceec, null, b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0, null, 1, 0, 1, 0, 0, 1, null, , null, 2024-11-12 14:59:44.311, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, Part1_Deployment, Part1_Deployment:1:0c957bc0-a0c1-11ef-9820-6ac6acfdceec, Part1_Deployment, 1, 0c82b70d-a0c1-11ef-9820-6ac6acfdceec, null
|
||||
* <== Total: 1
|
||||
* Closing JDBC Connection [Transaction-aware proxy for target Connection [HikariProxyConnection@1118158255 wrapping com.mysql.cj.jdbc.ConnectionImpl@77eb0e47]]
|
||||
* ProcessInstanceId:b25a64f9-a0c3-11ef-8ba8-68c6acfdcef0
|
||||
* ProcessDefinitionId:Part1_Deployment:1:0c957bc0-a0c1-11ef-9820-6ac6acfdceec
|
||||
* isEnded:false
|
||||
* isSuspended:false
|
||||
*/
|
||||
|
||||
// 查询流程实例列表
|
||||
List<ProcessInstance> processInstanceList = this.runtimeService.createProcessInstanceQuery().list();
|
||||
if (!CollectionUtils.isEmpty(processInstanceList)) {
|
||||
processInstanceList.forEach(pi -> {
|
||||
System.out.println("ProcessInstanceId:" + pi.getProcessInstanceId());
|
||||
System.out.println("ProcessDefinitionId:" + pi.getProcessDefinitionId());
|
||||
System.out.println("isEnded:" + pi.isEnded());
|
||||
System.out.println("isSuspended:" + pi.isSuspended());
|
||||
});
|
||||
}
|
||||
// 挂起流程实例
|
||||
this.runtimeService.suspendProcessInstanceById(processInstanceId);
|
||||
// 激活流程实例
|
||||
this.runtimeService.activateProcessInstanceById(processInstanceId);
|
||||
// 删除流程实例
|
||||
this.runtimeService.deleteProcessInstance(processInstanceId, "测试删除流程实例");
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
## **流程符号**
|
||||
|
||||
### 事件 Event
|
||||
|
||||
![img](http://42.192.130.83:9000/picgo/imgs/v2-7abf29716c8a87df55a503f537b86230_1440w.jpg_repeat_1731401500483__988588.png)
|
||||
|
||||
### **网关 GateWay**
|
||||
|
||||
![img](http://42.192.130.83:9000/picgo/imgs/v2-f27e0ae9d25d13b7b0cc90fceaffd732_1440w.jpg_repeat_1731401505552__805264.png)
|
||||
|
||||
- 排他网关:只有一条路径会被选择
|
||||
- 并行网关:所有路径都会被选择
|
||||
- 包容网关:可以在网关上设置条件,**为每个输出设置计算**
|
||||
- 事件网关:进入等待状态,**等待事件后转为活动状态**
|
||||
|
||||
### 流向 Flow
|
||||
|
||||
![img](http://42.192.130.83:9000/picgo/imgs/v2-9f863cc8aa78ed965a8a50349bcd3304_1440w.jpg_repeat_1731401793171__863727.png)
|
||||
|
||||
##
|
||||
|
111
ForJdk17/src/main/java/cn/whaifree/interview/ct/P1.java
Normal file
111
ForJdk17/src/main/java/cn/whaifree/interview/ct/P1.java
Normal file
@ -0,0 +1,111 @@
|
||||
package cn.whaifree.interview.ct;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
* @Author whai文海
|
||||
* @Date 2024/11/13 21:18
|
||||
* @注释
|
||||
*/
|
||||
public class P1 {
|
||||
|
||||
// Method to parse configurations
|
||||
private static void parseConfig(List<String> lines, Set<String> physical, Map<String, List<String>> bonds, Map<String, String> vlans) {
|
||||
for (String line : lines) {
|
||||
String[] parts = line.split(" ");
|
||||
switch (parts[0]) {
|
||||
case "Physical":
|
||||
physical.add(parts[1]);
|
||||
break;
|
||||
case "Bond":
|
||||
String bondName = parts[1];
|
||||
List<String> children = new ArrayList<>(Arrays.asList(parts).subList(3, parts.length));
|
||||
Collections.sort(children);
|
||||
bonds.put(bondName, children);
|
||||
break;
|
||||
case "VLAN":
|
||||
vlans.put(parts[1], parts[2]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Method to calculate minimum steps
|
||||
public static int calculateMinSteps(List<String> currentLines, List<String> targetLines) {
|
||||
// Parsing current and target configurations
|
||||
Set<String> currentPhysical = new HashSet<>();
|
||||
Map<String, List<String>> currentBonds = new HashMap<>();
|
||||
Map<String, String> currentVlans = new HashMap<>();
|
||||
parseConfig(currentLines, currentPhysical, currentBonds, currentVlans);
|
||||
|
||||
Set<String> targetPhysical = new HashSet<>();
|
||||
Map<String, List<String>> targetBonds = new HashMap<>();
|
||||
Map<String, String> targetVlans = new HashMap<>();
|
||||
parseConfig(targetLines, targetPhysical, targetBonds, targetVlans);
|
||||
|
||||
int steps = 0;
|
||||
|
||||
// Step 1: Delete extra bonds and vlans in the current configuration
|
||||
for (String bond : new HashSet<>(currentBonds.keySet())) {
|
||||
if (!targetBonds.containsKey(bond)) {
|
||||
currentBonds.remove(bond);
|
||||
steps++;
|
||||
}
|
||||
}
|
||||
for (String vlan : new HashSet<>(currentVlans.keySet())) {
|
||||
if (!targetVlans.containsKey(vlan)) {
|
||||
currentVlans.remove(vlan);
|
||||
steps++;
|
||||
}
|
||||
}
|
||||
|
||||
// Step 2: Add missing bonds and vlans in the current configuration
|
||||
for (Map.Entry<String, List<String>> entry : targetBonds.entrySet()) {
|
||||
String bond = entry.getKey();
|
||||
List<String> targetChildren = entry.getValue();
|
||||
if (!currentBonds.containsKey(bond)) {
|
||||
currentBonds.put(bond, targetChildren);
|
||||
steps++;
|
||||
} else if (!currentBonds.get(bond).equals(targetChildren)) {
|
||||
currentBonds.put(bond, targetChildren);
|
||||
steps++;
|
||||
}
|
||||
}
|
||||
|
||||
for (Map.Entry<String, String> entry : targetVlans.entrySet()) {
|
||||
String vlan = entry.getKey();
|
||||
String targetParent = entry.getValue();
|
||||
if (!currentVlans.containsKey(vlan)) {
|
||||
currentVlans.put(vlan, targetParent);
|
||||
steps++;
|
||||
} else if (!currentVlans.get(vlan).equals(targetParent)) {
|
||||
currentVlans.put(vlan, targetParent);
|
||||
steps++;
|
||||
}
|
||||
}
|
||||
|
||||
return steps;
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
Scanner scanner = new Scanner(System.in);
|
||||
|
||||
int n = Integer.parseInt(scanner.nextLine());
|
||||
List<String> currentLines = new ArrayList<>();
|
||||
for (int i = 0; i < n; i++) {
|
||||
currentLines.add(scanner.nextLine().trim());
|
||||
}
|
||||
|
||||
int m = Integer.parseInt(scanner.nextLine());
|
||||
List<String> targetLines = new ArrayList<>();
|
||||
for (int i = 0; i < m; i++) {
|
||||
targetLines.add(scanner.nextLine().trim());
|
||||
}
|
||||
|
||||
int result = calculateMinSteps(currentLines, targetLines);
|
||||
System.out.println(result);
|
||||
|
||||
scanner.close();
|
||||
}
|
||||
|
||||
}
|
@ -60,6 +60,8 @@ class p2{
|
||||
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
|
||||
*
|
||||
*
|
||||
* 给你一个数组,你可以随意操作任意相邻的元素都+1,请问需要多少次可以让整个数组变成对称的
|
||||
*
|
||||
* @param arr int整型一维数组
|
||||
* @return long长整型
|
||||
*/
|
||||
@ -80,4 +82,44 @@ class p2{
|
||||
int i = dp[0][n - 1];
|
||||
return i;
|
||||
}
|
||||
|
||||
public static class Solution {
|
||||
public int minOperations(int[] arr) {
|
||||
int n = arr.length;
|
||||
|
||||
// 如果数组长度是奇数,中心元素不参与对称操作
|
||||
int operations = 0;
|
||||
|
||||
// 使用双指针,从两端往中间移动
|
||||
for (int i = 0; i < n / 2; i++) {
|
||||
int left = arr[i];
|
||||
int right = arr[n - i - 1];
|
||||
|
||||
// 计算两个元素的差值
|
||||
int diff = Math.abs(left - right);
|
||||
|
||||
// 如果差值是奇数,不能通过 +1 操作得到相等的数
|
||||
if (diff % 2 != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 每次需要 diff / 2 次操作来平衡这两个元素
|
||||
operations += diff / 2;
|
||||
}
|
||||
|
||||
return operations;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Solution solution = new Solution();
|
||||
|
||||
// 示例测试
|
||||
int[] arr1 = {1, 2, 2, 1, 1};
|
||||
System.out.println(solution.minOperations(arr1)); // 输出: 0
|
||||
|
||||
int[] arr2 = {1, 2, 3, 4, 5};
|
||||
System.out.println(solution.minOperations(arr2)); // 输出: -1
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,98 @@
|
||||
package cn.whaifree.leetCode;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
* @Author whai文海
|
||||
* @Date 2024/11/12 11:47
|
||||
* @注释
|
||||
*/
|
||||
public class LeetCode1648 {
|
||||
|
||||
// @Test
|
||||
// public void test() {
|
||||
// int[] inventory = {1000000000};
|
||||
// int res = new Solution().maxProfit(inventory, 1000000000);
|
||||
// System.out.println(res);
|
||||
// }
|
||||
//
|
||||
// class Solution {
|
||||
//
|
||||
//
|
||||
// /**
|
||||
// * 数量最多的同色球的数量 和 球数 == MAX 的颜色的数量。
|
||||
// *
|
||||
// * @param inventory
|
||||
// * @param orders
|
||||
// * @return
|
||||
// */
|
||||
// public int maxProfit(int[] inventory, int orders) {
|
||||
//
|
||||
// Arrays.sort(inventory);
|
||||
//
|
||||
// int res = 0;
|
||||
// int countOfColor = 1;
|
||||
// for (int i = inventory.length - 1; i > 0; i--) {
|
||||
// int end = inventory[i];
|
||||
// int start = inventory[i - 1];
|
||||
// for (int j = end; j > start; j--) {
|
||||
// for (int x = 0; x < countOfColor; x++) {
|
||||
// res += j;
|
||||
// inventory[i]--;
|
||||
// orders--;
|
||||
// if (orders == 0) {
|
||||
// return res;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// countOfColor++;
|
||||
// }
|
||||
//
|
||||
// // 最后变为 x x x x (x为最小值)
|
||||
//
|
||||
//
|
||||
// for (int j = 0; j < inventory[0]; j++) {
|
||||
// int item = inventory[0];
|
||||
// if (orders < inventory.length) {
|
||||
// return res + orders * item;
|
||||
// }else {
|
||||
// for (int i = 0; i < item; i++) {
|
||||
// res += inventory[0];
|
||||
// orders--;
|
||||
// if (orders == 0) {
|
||||
// return res;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return res;
|
||||
//
|
||||
//
|
||||
// // 5 2 2 1 2 1
|
||||
//
|
||||
//
|
||||
//// int res = 0;
|
||||
//// int add = 1;
|
||||
////
|
||||
//// int right = inventory.length - 1;
|
||||
//// for (int i = 0; i < orders; i++) {
|
||||
//// int left = right - 1;
|
||||
////
|
||||
//// int leftV = inventory[left];
|
||||
//// int rightV = inventory[right];
|
||||
//// for (int j = rightV; j > leftV; j--) {
|
||||
////
|
||||
//// }
|
||||
//// right--;
|
||||
//// }
|
||||
//// return res;
|
||||
//
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
@ -0,0 +1,118 @@
|
||||
package cn.whaifree.redo.redo_all_241016;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
* @Author whai文海
|
||||
* @Date 2024/11/15 9:56
|
||||
* @注释
|
||||
*/
|
||||
public class LeetCode210_207 {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
int numCourses = 2;
|
||||
int[][] prerequisites = {};
|
||||
Solution solution = new Solution();
|
||||
int[] ints = solution.findOrder(numCourses, prerequisites);
|
||||
System.out.println(Arrays.toString(ints));
|
||||
}
|
||||
|
||||
class Solution {
|
||||
public int[] findOrder(int numCourses, int[][] prerequisites) {
|
||||
// prerequisites[i] = [ai, bi] ,表示在选修课程 ai 前 必须 先选修 bi
|
||||
|
||||
Map<Integer, List<Integer>> map = new HashMap<>();
|
||||
int[] in = new int[numCourses];
|
||||
|
||||
for (int i = 0; i < numCourses; i++) {
|
||||
map.put(i, new ArrayList<>());
|
||||
}
|
||||
|
||||
for (int[] prerequisite : prerequisites) {
|
||||
in[prerequisite[0]]++;
|
||||
map.get(prerequisite[1]).add(prerequisite[0]);
|
||||
}
|
||||
|
||||
Deque<Integer> deque = new ArrayDeque<>();
|
||||
// 入度炜0的
|
||||
for (int i = 0; i < in.length; i++) {
|
||||
if (in[i] == 0) {
|
||||
deque.push(i);
|
||||
}
|
||||
}
|
||||
|
||||
int[] res = new int[numCourses];
|
||||
int index = 0;
|
||||
while (!deque.isEmpty()) {
|
||||
// 入度为0
|
||||
Integer pop = deque.pop();
|
||||
res[index++] = pop;
|
||||
|
||||
List<Integer> into = map.get(pop);
|
||||
for (Integer i : into) {
|
||||
in[i]--;
|
||||
if (in[i] == 0) {
|
||||
deque.add(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (index != numCourses) {
|
||||
return new int[0];
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
class Solution1 {
|
||||
public boolean canFinish(int numCourses, int[][] prerequisites) {
|
||||
// prerequisites[i] = [ai, bi] ,表示在选修课程 ai 前 必须 先选修 bi
|
||||
|
||||
Map<Integer, List<Integer>> map = new HashMap<>();
|
||||
int[] in = new int[numCourses];
|
||||
|
||||
for (int i = 0; i < numCourses; i++) {
|
||||
map.put(i, new ArrayList<>());
|
||||
}
|
||||
|
||||
for (int[] prerequisite : prerequisites) {
|
||||
in[prerequisite[0]]++;
|
||||
map.get(prerequisite[1]).add(prerequisite[0]);
|
||||
}
|
||||
|
||||
Deque<Integer> deque = new ArrayDeque<>();
|
||||
// 入度炜0的
|
||||
for (int i = 0; i < in.length; i++) {
|
||||
if (in[i] == 0) {
|
||||
deque.push(i);
|
||||
}
|
||||
}
|
||||
|
||||
int[] res = new int[numCourses];
|
||||
int index = 0;
|
||||
while (!deque.isEmpty()) {
|
||||
// 入度为0
|
||||
Integer pop = deque.pop();
|
||||
res[index++] = pop;
|
||||
|
||||
List<Integer> into = map.get(pop);
|
||||
for (Integer i : into) {
|
||||
in[i]--;
|
||||
if (in[i] == 0) {
|
||||
deque.add(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (index != numCourses) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
package cn.whaifree.redo.redo_all_241016;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
* @Author whai文海
|
||||
* @Date 2024/11/16 17:01
|
||||
* @注释
|
||||
*/
|
||||
public class LeetCode2602 {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
int[] nums = {3,1,6,8};
|
||||
int[] queries = {1,5};
|
||||
Solution solution = new Solution();
|
||||
System.out.println(solution.minOperations(nums, queries));
|
||||
}
|
||||
|
||||
class Solution {
|
||||
public List<Long> minOperations(int[] nums, int[] queries) {
|
||||
// 1 3 6 8
|
||||
// 1 4 10 18
|
||||
Arrays.sort(nums);
|
||||
// 前缀和
|
||||
long[] preSum = new long[nums.length + 1];
|
||||
for (int i = 1; i <= nums.length; i++) {
|
||||
preSum[i] = preSum[i - 1] + nums[i - 1];
|
||||
}
|
||||
List<Long> list = new ArrayList<>();
|
||||
for (int i = 0; i < queries.length; i++) {
|
||||
long l = minOpr(preSum, nums, queries[i]);
|
||||
list.add(l);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
public long minOpr(long[] preSum, int[] nums, int queries) {
|
||||
int index = Arrays.binarySearch(nums, queries);
|
||||
if (index < 0) {
|
||||
index = -index - 1;
|
||||
}
|
||||
|
||||
// 前面的次数
|
||||
long preSize = preSum[index];
|
||||
long before = (long) index * queries - preSize;
|
||||
long afterSize = preSum[nums.length] - preSize;
|
||||
long after = afterSize - (long) (nums.length - index) * queries;
|
||||
|
||||
return (before + after);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
package cn.whaifree.redo.redo_all_241016;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
* @Author whai文海
|
||||
* @Date 2024/11/14 17:17
|
||||
* @注释
|
||||
*/
|
||||
public class LeetCode469_1 {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
String s = "2001:0db8:85a3:0:0:8A2E:0370:7334";
|
||||
System.out.println(new Solution().validIPAddress(s));
|
||||
}
|
||||
|
||||
class Solution {
|
||||
public String validIPAddress(String queryIP) {
|
||||
if (queryIP.contains(":") && isIpv6(queryIP.split(":", -1))) {
|
||||
return "IPv6";
|
||||
} else if (queryIP.contains(".") && isIpv4(queryIP.split("\\.", -1))) {
|
||||
return "IPv4";
|
||||
}
|
||||
return "Neither";
|
||||
}
|
||||
|
||||
public boolean isIpv6(String[] ips) {
|
||||
if (ips.length != 8) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
for (String ip : ips) {
|
||||
if (ip.isEmpty() || ip.length() > 4) {
|
||||
return false;
|
||||
}
|
||||
int i = Integer.parseInt(ip, 16);
|
||||
}
|
||||
}catch (Exception e){
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isIpv4(String[] ip) {
|
||||
if (ip.length != 4) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < ip.length; i++) {
|
||||
String s = ip[i];
|
||||
try {
|
||||
if (s.length() > 1 && s.startsWith("0")) {
|
||||
return false;
|
||||
}
|
||||
Integer num = Integer.valueOf(s);
|
||||
if (num < 0 || num > 255) {
|
||||
return false;
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
103
ForJdk17/src/main/java/cn/whaifree/tech/GRRXReference.java
Normal file
103
ForJdk17/src/main/java/cn/whaifree/tech/GRRXReference.java
Normal file
@ -0,0 +1,103 @@
|
||||
package cn.whaifree.tech;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.lang.ref.PhantomReference;
|
||||
import java.lang.ref.ReferenceQueue;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
* @Author whai文海
|
||||
* @Date 2024/11/15 21:22
|
||||
* @注释
|
||||
*/
|
||||
public class GRRXReference {
|
||||
|
||||
@Test
|
||||
public void soft() {
|
||||
Object obj = new Object();
|
||||
SoftReference<Object> softRef = new SoftReference<>(obj); // 创建软引用
|
||||
|
||||
// 手动触发垃圾回收
|
||||
System.gc();
|
||||
|
||||
// 尝试获取软引用指向的对象
|
||||
Object retrievedObject = softRef.get();
|
||||
if (retrievedObject != null) {
|
||||
System.out.println("对象还在内存中: " + retrievedObject);
|
||||
} else {
|
||||
System.out.println("对象已经被垃圾回收");
|
||||
}
|
||||
|
||||
// 使 obj 可被回收
|
||||
obj = null;
|
||||
|
||||
// 再次尝试获取软引用指向的对象
|
||||
System.gc(); // 强烈建议调用 GC 来验证软引用回收
|
||||
retrievedObject = softRef.get();
|
||||
if (retrievedObject != null) {
|
||||
System.out.println("对象还在内存中: " + retrievedObject);
|
||||
} else {
|
||||
System.out.println("对象已经被垃圾回收");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void weak() {
|
||||
Object obj = new Object();
|
||||
WeakReference<Object> weakRef = new WeakReference<>(obj); // 创建弱引用
|
||||
|
||||
// 手动触发垃圾回收
|
||||
System.gc();
|
||||
|
||||
// 尝试获取软引用指向的对象
|
||||
Object retrievedObject = weakRef.get();
|
||||
if (retrievedObject != null) {
|
||||
System.out.println("对象还在内存中: " + retrievedObject);
|
||||
} else {
|
||||
System.out.println("对象已经被垃圾回收");
|
||||
}
|
||||
|
||||
// 使 obj 可被回收
|
||||
obj = null;
|
||||
|
||||
// 再次尝试获取软引用指向的对象
|
||||
System.gc(); // 强烈建议调用 GC 来验证软引用回收
|
||||
retrievedObject = weakRef.get();
|
||||
if (retrievedObject != null) {
|
||||
System.out.println("对象还在内存中: " + retrievedObject);
|
||||
} else {
|
||||
System.out.println("对象已经被垃圾回收");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void phantom() {
|
||||
// 创建一个引用队列
|
||||
ReferenceQueue<Object> queue = new ReferenceQueue<>();
|
||||
|
||||
// 创建一个对象和它的虚引用
|
||||
Object obj = new Object();
|
||||
PhantomReference<Object> phantomRef = new PhantomReference<>(obj, queue);
|
||||
|
||||
System.out.println("虚引用创建完毕,obj 是:" + phantomRef.get());
|
||||
|
||||
// 使 obj 可被回收
|
||||
obj = null;
|
||||
|
||||
// 手动触发垃圾回收
|
||||
System.gc();
|
||||
|
||||
// 检查引用队列中是否有虚引用指向的对象
|
||||
try {
|
||||
// 只有在对象被回收后,才会从引用队列中取得虚引用
|
||||
PhantomReference<?> refFromQueue = (PhantomReference<?>) queue.remove();
|
||||
System.out.println("虚引用指向的对象已经被回收:" + refFromQueue);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package cn.whaifree.tech.SPI;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
* @Author whai文海
|
||||
* @Date 2024/11/15 21:31
|
||||
* @注释
|
||||
*/
|
||||
public class ASPIServiceImpl implements SPIService {
|
||||
@Override
|
||||
public void sayHello() {
|
||||
System.out.println("Hello, I am ASPIServiceImpl");
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package cn.whaifree.tech.SPI;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
* @Author whai文海
|
||||
* @Date 2024/11/15 21:31
|
||||
* @注释
|
||||
*/
|
||||
public class BSPIServiceImpl implements SPIService {
|
||||
@Override
|
||||
public void sayHello() {
|
||||
System.out.println("BSPIServiceImpl sayHello");
|
||||
}
|
||||
}
|
28
ForJdk17/src/main/java/cn/whaifree/tech/SPI/SPIService.java
Normal file
28
ForJdk17/src/main/java/cn/whaifree/tech/SPI/SPIService.java
Normal file
@ -0,0 +1,28 @@
|
||||
package cn.whaifree.tech.SPI;
|
||||
|
||||
import java.security.Provider;
|
||||
import java.util.Iterator;
|
||||
import java.util.ServiceLoader;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
* @Author whai文海
|
||||
* @Date 2024/11/15 21:31
|
||||
* @注释
|
||||
*/
|
||||
public interface SPIService {
|
||||
void sayHello();
|
||||
|
||||
|
||||
static void main(String[] args) {
|
||||
|
||||
|
||||
ServiceLoader<SPIService> load = ServiceLoader.load(SPIService.class);
|
||||
Iterator<SPIService> iterator = load.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
SPIService next = iterator.next();
|
||||
next.sayHello();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package cn.whaifree.test;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@ -18,6 +19,14 @@ public class FanxinTest {
|
||||
new LinkedBlockingQueue<>()
|
||||
);
|
||||
|
||||
// 异步
|
||||
threadPoolExecutor.submit(new Callable<Object>() {
|
||||
@Override
|
||||
public Object call() throws Exception {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -53,6 +53,7 @@ public class ThreadDemo1 {
|
||||
public static void main(String[] args) throws InterruptedException {
|
||||
|
||||
AtomicInteger num = new AtomicInteger(9);
|
||||
num.decrementAndGet();
|
||||
CountDownLatch countDownLatch = new CountDownLatch(num.get());
|
||||
|
||||
for (int i = 0; i < 9; i++) {
|
||||
|
@ -142,6 +142,9 @@ class BioServer {
|
||||
|
||||
class NioServer {
|
||||
public static void main(String[] args) throws IOException {
|
||||
|
||||
|
||||
|
||||
// 打开一个选择器
|
||||
Selector selector = Selector.open();
|
||||
// 打开一个服务器套接字通道
|
||||
|
@ -14,6 +14,24 @@ import java.util.concurrent.TimeUnit;
|
||||
public class ScheduledThreadPoolTest {
|
||||
volatile static Integer i = 0;
|
||||
|
||||
/**
|
||||
* 提交任务时,消费任务的时候检查 ScheduledFutureTask 时间
|
||||
*
|
||||
* 任务提交:当用户提交一个定时任务时,ScheduledThreadPool 会将任务封装成 ScheduledFutureTask 对象,并将其放入延迟队列中。
|
||||
*
|
||||
* 任务调度:线程池中的线程会从延迟队列中取出任务并执行。如果任务设置了延迟执行时间,线程会等待相应的时间后再执行任务。
|
||||
*
|
||||
* 任务执行:线程执行任务时,会调用 ScheduledFutureTask 的 run 方法。run 方法会首先检查任务的取消状态,如果任务被取消,则直接返回。否则,会执行任务的 run 方法。
|
||||
*
|
||||
* 周期性任务:对于周期性任务,ScheduledFutureTask 会根据任务的执行周期重新计算下一次执行的时间,并将其重新放入延迟队列中。这样,周期性任务会按照指定的周期重复执行。
|
||||
*
|
||||
* 异常处理:如果任务在执行过程中抛出异常,ScheduledFutureTask 会捕获这个异常,并调用 setException 方法将异常设置到 Future 对象中。
|
||||
*
|
||||
* 任务完成:当任务执行完成后,ScheduledFutureTask 会从延迟队列中移除,并更新 Future 对象的状态。
|
||||
*
|
||||
* 线程回收:ScheduledThreadPool 中的线程会根据任务的执行情况进行回收。如果线程池中的线程在一段时间内没有任务可执行,它们会被回收,以减少资源消耗。
|
||||
* @param args
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
|
||||
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(10);
|
||||
|
@ -0,0 +1,2 @@
|
||||
cn.whaifree.tech.SPI.ASPIServiceImpl
|
||||
cn.whaifree.tech.SPI.BSPIServiceImpl
|
@ -17,7 +17,9 @@ public class FunctionInterfaceDemo {
|
||||
|
||||
public static void main(String[] args) throws InterruptedException {
|
||||
|
||||
HashMap<Object, Object> map = new HashMap<>();
|
||||
ConcurrentHashMap<Object, Object> map = new ConcurrentHashMap<>();
|
||||
map.put(null, null);
|
||||
// HashMap<Object, Object> map = new HashMap<>();
|
||||
// map.put(null, null);
|
||||
System.out.println(map.get(null));
|
||||
|
||||
|
171
SpringCloud/GateWay/pom.xml
Normal file
171
SpringCloud/GateWay/pom.xml
Normal file
@ -0,0 +1,171 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>3.3.5</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<groupId>com.whai.springcloud</groupId>
|
||||
<artifactId>GateWay</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>GateWay</name>
|
||||
<description>GateWay</description>
|
||||
<url/>
|
||||
<licenses>
|
||||
<license/>
|
||||
</licenses>
|
||||
<developers>
|
||||
<developer/>
|
||||
</developers>
|
||||
<scm>
|
||||
<connection/>
|
||||
<developerConnection/>
|
||||
<tag/>
|
||||
<url/>
|
||||
</scm>
|
||||
<properties>
|
||||
<java.version>17</java.version>
|
||||
<spring-cloud.version>2023.0.3</spring-cloud.version>
|
||||
<swagger.fox.version>3.0.0</swagger.fox.version>
|
||||
|
||||
</properties>
|
||||
<dependencies>
|
||||
|
||||
<!-- SpringCloud Gateway -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-gateway</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- SpringCloud Alibaba Nacos -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- SpringCloud Alibaba Nacos Config -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- SpringCloud Alibaba Sentinel -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- SpringCloud Alibaba Sentinel Gateway -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Sentinel Datasource Nacos -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-datasource-nacos</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Sentinel 实时监控 -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-transport-simple-http</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- SpringBoot Actuator -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- SpringCloud Loadbalancer -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-loadbalancer</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!--验证码 -->
|
||||
<dependency>
|
||||
<groupId>pro.fessional</groupId>
|
||||
<artifactId>kaptcha</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!-- Swagger -->
|
||||
<dependency>
|
||||
<groupId>io.springfox</groupId>
|
||||
<artifactId>springfox-swagger-ui</artifactId>
|
||||
<version>${swagger.fox.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.springfox</groupId>
|
||||
<artifactId>springfox-swagger2</artifactId>
|
||||
<version>${swagger.fox.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- knife4j -->
|
||||
<dependency>
|
||||
<groupId>com.github.xiaoymin</groupId>
|
||||
<artifactId>knife4j-spring-ui</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.xiaoymin</groupId>
|
||||
<artifactId>knife4j-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>${project.artifactId}</finalName>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<!-- 为防止打包docker部署读取不到配置文件问题资源文件 -->
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/java</directory>
|
||||
<includes>
|
||||
<include>**/*.yml</include>
|
||||
<include>**/*.properties</include>
|
||||
<include>**/*.xml</include>
|
||||
</includes>
|
||||
<filtering>false</filtering>
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<includes>
|
||||
<include>**/*.yml</include>
|
||||
<include>**/*.properties</include>
|
||||
<include>**/*.xml</include>
|
||||
</includes>
|
||||
<filtering>false</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
|
||||
</build>
|
||||
|
||||
</project>
|
@ -0,0 +1,13 @@
|
||||
package com.whai.springcloud.gateway;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class GateWayApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(GateWayApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1 @@
|
||||
spring.application.name=GateWay
|
48
SpringCloud/GateWay/src/main/resources/bootstrap.yml
Normal file
48
SpringCloud/GateWay/src/main/resources/bootstrap.yml
Normal file
@ -0,0 +1,48 @@
|
||||
# Tomcat
|
||||
server:
|
||||
port: 6880
|
||||
|
||||
# Spring
|
||||
spring:
|
||||
application:
|
||||
# 应用名称
|
||||
name: whai-gateway
|
||||
cloud:
|
||||
nacos:
|
||||
discovery:
|
||||
# 服务注册地址
|
||||
server-addr: 192.168.50.248:8848
|
||||
username: nacos
|
||||
password: nacos
|
||||
config:
|
||||
# 配置中心地址
|
||||
server-addr: 192.168.50.248:8848
|
||||
username: nacos
|
||||
password: nacos
|
||||
# 配置文件格式
|
||||
file-extension: yml
|
||||
# 共享配置
|
||||
shared-configs:
|
||||
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
|
||||
# sentinel:
|
||||
# # 取消控制台懒加载
|
||||
# eager: true
|
||||
# transport:
|
||||
# # 配置控制台服务地址
|
||||
# dashboard: 127.0.0.1:8080
|
||||
# # 默认 8719 端口,假如被占用会自动从 8719 开始依次 +1 扫描,直至找到未被占用的端口
|
||||
# port: 8719
|
||||
# # nacos配置持久化
|
||||
# datasource:
|
||||
# ds1:
|
||||
# nacos:
|
||||
# server-addr: 127.0.0.1:8848
|
||||
# dataId: sentinel-pmhub-gateway
|
||||
# groupId: DEFAULT_GROUP
|
||||
# data-type: json
|
||||
# rule-type: gw-flow
|
||||
|
||||
# 实时log配置,可在http://localhost:6888/ 监控中心查看实时日志
|
||||
logging:
|
||||
file:
|
||||
name: logs/${spring.application.name}/info.log
|
@ -0,0 +1,13 @@
|
||||
package com.whai.springcloud.gateway;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
@SpringBootTest
|
||||
class GateWayApplicationTests {
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
}
|
||||
|
||||
}
|
@ -30,6 +30,7 @@
|
||||
<java.version>17</java.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
|
@ -16,7 +16,7 @@ import org.springframework.web.client.RestTemplate;
|
||||
public class RestConfig {
|
||||
@Bean
|
||||
@LoadBalanced
|
||||
public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) {
|
||||
return restTemplateBuilder.build();
|
||||
public RestTemplate restTemplate() {
|
||||
return new RestTemplateBuilder().build();
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,4 @@ public interface BService {
|
||||
@GetMapping("/getB")
|
||||
String getB(@RequestParam("msg") String msg);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
|
||||
server:
|
||||
port: 12120
|
||||
port: 12123
|
||||
spring:
|
||||
application:
|
||||
name: ServiceA
|
||||
@ -8,20 +9,20 @@ spring:
|
||||
username: nacos
|
||||
password: nacos
|
||||
discovery:
|
||||
namespace: 97ff159f-6177-4aab-b735-bd75458949d4
|
||||
namespace: public
|
||||
group: DEFAULT_GROUP
|
||||
server-addr: localhost:8848
|
||||
server-addr: 192.168.50.248:8848
|
||||
config:
|
||||
# 配置所属命名空间的id,我们配置名称为dev的id,在命名空间列表查看id的值
|
||||
namespace: 97ff159f-6177-4aab-b735-bd75458949d4
|
||||
namespace: public
|
||||
# 文件名,如果没有配置则默认为 ${spring.application.name}
|
||||
# prefix: springboot3-nacos
|
||||
# prefix: springboot3-nacos
|
||||
# 配置所属分组
|
||||
group: DEFAULT_GROUP
|
||||
# 后缀名,只支持 properties 和 yaml 类型
|
||||
file-extension: yaml
|
||||
# nacos服务器地址
|
||||
server-addr: localhost:8848
|
||||
server-addr: ${spring.cloud.nacos.discovery.server-addr}
|
||||
# 配置自动刷新
|
||||
refresh-enabled: true
|
||||
config:
|
||||
@ -33,5 +34,3 @@ logging:
|
||||
level:
|
||||
com.hexadecimal: debug
|
||||
|
||||
hexadecimal:
|
||||
name: whai
|
||||
|
@ -30,6 +30,8 @@
|
||||
<java.version>17</java.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
|
@ -5,7 +5,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
|
||||
@SpringBootApplication
|
||||
@SpringBootApplication(scanBasePackages = {"com.whai.springcloud.serviceb"})
|
||||
@EnableDiscoveryClient
|
||||
@EnableFeignClients
|
||||
public class ServiceBApplication {
|
||||
|
@ -57,7 +57,7 @@ public class BProviderController {
|
||||
}
|
||||
|
||||
}
|
||||
@Value("${cvm.reset.ratelimit}")
|
||||
@Value("${cvm.reset.ratelimit:0}")
|
||||
private int rateLimitCount;
|
||||
private void initRateLimiter() {
|
||||
if (rateLimitCount <= 0) {
|
||||
@ -72,6 +72,11 @@ public class BProviderController {
|
||||
return StrUtil.format("BProviderController.getB, msg: {}, port: {}", msg, environment.getProperty("server.port"));
|
||||
}
|
||||
|
||||
@RequestMapping("/getProper")
|
||||
public int getProper() {
|
||||
return environment.getProperty("cvm.reset.ratelimit", Integer.class);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@PostMapping("/CVM/reset")
|
||||
|
@ -0,0 +1,27 @@
|
||||
package com.whai.springcloud.serviceb.controller;
|
||||
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.cloud.context.config.annotation.RefreshScope;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
* @Author whai文海
|
||||
* @Date 2024/11/16 14:24
|
||||
* @注释
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/config")
|
||||
@RefreshScope
|
||||
public class ConfigController {
|
||||
|
||||
@Value("${useLocalCache:false}")
|
||||
private boolean useLocalCache;
|
||||
|
||||
@RequestMapping("/get")
|
||||
public boolean get() {
|
||||
return useLocalCache;
|
||||
}
|
||||
}
|
@ -1,4 +1,6 @@
|
||||
|
||||
server:
|
||||
port: 12121
|
||||
spring:
|
||||
application:
|
||||
name: ServiceB
|
||||
@ -7,12 +9,12 @@ spring:
|
||||
username: nacos
|
||||
password: nacos
|
||||
discovery:
|
||||
namespace: 97ff159f-6177-4aab-b735-bd75458949d4
|
||||
namespace: public
|
||||
group: DEFAULT_GROUP
|
||||
server-addr: localhost:8848
|
||||
server-addr: 192.168.50.248:8848
|
||||
config:
|
||||
# 配置所属命名空间的id,我们配置名称为dev的id,在命名空间列表查看id的值
|
||||
namespace: 97ff159f-6177-4aab-b735-bd75458949d4
|
||||
namespace: public
|
||||
# 文件名,如果没有配置则默认为 ${spring.application.name}
|
||||
# prefix: springboot3-nacos
|
||||
# 配置所属分组
|
||||
@ -20,7 +22,7 @@ spring:
|
||||
# 后缀名,只支持 properties 和 yaml 类型
|
||||
file-extension: yaml
|
||||
# nacos服务器地址
|
||||
server-addr: localhost:8848
|
||||
server-addr: ${spring.cloud.nacos.discovery.server-addr}
|
||||
# 配置自动刷新
|
||||
refresh-enabled: true
|
||||
config:
|
||||
@ -32,5 +34,3 @@ logging:
|
||||
level:
|
||||
com.hexadecimal: debug
|
||||
|
||||
hexadecimal:
|
||||
name: whai
|
||||
|
@ -32,6 +32,9 @@
|
||||
<spring-cloud.version>2023.0.3</spring-cloud.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
|
||||
|
||||
|
||||
<!-- Lombok -->
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
|
@ -0,0 +1,97 @@
|
||||
package cn.whaifree.springdemo.config;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.TransactionDefinition;
|
||||
import org.springframework.transaction.TransactionManager;
|
||||
import org.springframework.transaction.TransactionStatus;
|
||||
import org.springframework.transaction.annotation.TransactionManagementConfigurer;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.transaction.support.DefaultTransactionDefinition;
|
||||
import org.springframework.transaction.support.TransactionCallback;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
* @Author whai文海
|
||||
* @Date 2024/11/15 16:37
|
||||
* @注释
|
||||
*/
|
||||
@Configuration
|
||||
@Slf4j
|
||||
public class TransactionConfig implements TransactionManagementConfigurer {
|
||||
|
||||
|
||||
@Autowired
|
||||
private TransactionTemplate transactionTemplate;
|
||||
|
||||
//配置事务管理器
|
||||
@Bean
|
||||
public TransactionManager transactionManager(DataSource dataSource) {
|
||||
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(dataSource);
|
||||
// 打印参数
|
||||
log.info("transactionManager: {}", transactionManager);
|
||||
log.info("dataSource: {}", dataSource);
|
||||
return transactionManager;
|
||||
}
|
||||
|
||||
@Resource(name="txManager1")
|
||||
private PlatformTransactionManager txManager1;
|
||||
|
||||
// 创建事务管理器1
|
||||
@Bean(name = "txManager1")
|
||||
public PlatformTransactionManager txManager(DataSource dataSource) {
|
||||
return new DataSourceTransactionManager(dataSource);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransactionManager annotationDrivenTransactionManager() {
|
||||
return txManager1;
|
||||
}
|
||||
|
||||
@Transactional(value="txManager1")
|
||||
public void addUser() {
|
||||
|
||||
}
|
||||
|
||||
public void addUser2() {
|
||||
DefaultTransactionDefinition transactionDefinition = new DefaultTransactionDefinition();
|
||||
transactionDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
|
||||
transactionDefinition.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
|
||||
TransactionStatus transaction = txManager1.getTransaction(transactionDefinition);
|
||||
try {
|
||||
txManager1.commit(transaction);
|
||||
} catch (Exception e) {
|
||||
txManager1.rollback(transaction);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 编程事务
|
||||
* TransactionTemplate
|
||||
* PlatformTransactionManager
|
||||
* DataSourceTransactionManager
|
||||
*/
|
||||
|
||||
public void adduser3() {
|
||||
Object execute = transactionTemplate.execute(new TransactionCallback<Object>() {
|
||||
@Override
|
||||
public Object doInTransaction(TransactionStatus status) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
class Tran{
|
||||
|
||||
}
|
@ -64,7 +64,7 @@ public class TestController {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object call() throws Exception {
|
||||
public Object call(){
|
||||
|
||||
return null;
|
||||
}
|
||||
|
@ -0,0 +1,52 @@
|
||||
package cn.whaifree.springdemo.mybatis;
|
||||
|
||||
import cn.whaifree.springdemo.mybatis.domain.AmountBig;
|
||||
import org.apache.ibatis.type.BaseTypeHandler;
|
||||
import org.apache.ibatis.type.JdbcType;
|
||||
|
||||
import java.sql.*;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
* @Author whai文海
|
||||
* @Date 2024/11/15 10:52
|
||||
* @注释
|
||||
*/
|
||||
public class AmountTypeHandler extends BaseTypeHandler<AmountBig> {
|
||||
|
||||
/**
|
||||
* 该方法用于将 AmountBig 枚举类型的值设置到 PreparedStatement 中,
|
||||
* @param ps
|
||||
* @param i
|
||||
* @param parameter
|
||||
* @param jdbcType
|
||||
* @throws SQLException
|
||||
*/
|
||||
@Override
|
||||
public void setNonNullParameter(PreparedStatement ps, int i, AmountBig parameter, JdbcType jdbcType) throws SQLException {
|
||||
if (parameter.equals(AmountBig.BIG)) {
|
||||
ps.setDouble(i, 1000000000D);
|
||||
}else {
|
||||
ps.setDouble(i, 0D);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AmountBig getNullableResult(ResultSet rs, String columnName) throws SQLException {
|
||||
double aDouble = rs.getDouble(columnName);
|
||||
if (aDouble == 1000000000D) {
|
||||
return AmountBig.BIG;
|
||||
}
|
||||
return AmountBig.SMALL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AmountBig getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AmountBig getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package cn.whaifree.springdemo.mybatis.domain;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
* @Author whai文海
|
||||
* @Date 2024/11/15 10:50
|
||||
* @注释
|
||||
*/
|
||||
public enum AmountBig {
|
||||
BIG,
|
||||
SMALL
|
||||
}
|
Loading…
Reference in New Issue
Block a user