ACT_ID_*:与权限,用户与用户组,以及用户与用户组关系相关的表

ACT_RU_*:代表了流程引擎运行时的库表,RU表示Runtime

ACT_HI_*:HI表示History当流程完成了节点以后,就将其迁移到历史数据库表


ACT_GE_*(通用数据库 )涉及到两个表:

act_ge_property:属性表,保存一些流程引擎的kv键值属性

对应数据库实体:PropertyEntityImpl


act_ge_bytearray:资源表,存储的是一些流程定义的资源信息(包括流程定义文件xml、流程定义的流程图,都被序列化成字节流存储在资源表里)

对应数据库实体:ByteArrayEntityImpl

定义有两种方式,可以用他的自动部署,也可以手动。

  1. public class DbConfigTest {
  2. private static final Logger LOGGER = LoggerFactory.getLogger(configDBTest.class);
  3.  
  4. @Rule
  5. public ActivitiRule activitiRule = new ActivitiRule("activiti_druid.cfg.xml");//传入自定义的mdc配置文件
  6.  
  7. @Test
  8. public void testDbConfig(){
  9. //自动
  10. activitiRule.getRepositoryService()
  11. .createDeployment()
  12. .name("指定部署名称")
  13. .addClasspathResource("my-process.bpmn20.xml");
  14. }
  15.  
  16. //手工添加act_ge_bytearray资源库信息
  17. @Test
  18. public void testbytearrayinsert(){
  19. //获取managementService,通过managementService去执行命令
  20. ManagementService managementService = activitiRule.getManagementService();
  21. Object o = managementService.executeCommand(new Command<Object>() {
  22.  
  23. @Override
  24. public Object execute(CommandContext commandContext) {
  25. ByteArrayEntity entity = new ByteArrayEntityImpl();
  26. entity.setName("test");
  27. entity.setBytes("test message".getBytes());
  28. //根据上下文获取对象
  29. commandContext.getByteArrayEntityManager().insert(entity);
  30.  
  31. return null;
  32. }
  33. });
  34.  
  35. }
  36. }

看数据库表效果:



ACT_RE_*(流程定义存储表)设计到四张表:

存储的都是些流程信息的名字等信息。


ACT_ID_*(身份数据表)涉及到四个表:

ACT_ID_USER对应实体UserEntityImpl

ID_:对应登录的用户名

REV_:版本信息

FIRST_:firstname

LAST_:lastname

EMAIL_:email

PWD_:password

PICTURE_ID_:对应用户头像信息,即头像的url

ACT_ID_INFO对应实体IdentityInfoEntityImpl

TYPE_:类型,针对user的

KEY_:属性名

VALUE_;属性值

如果要用key与value扩展,例如:key可以放age,value可以放18;

PASSWORD_:密码(并没有使用到)

PARENT_ID_:上级关联(这个字段表明了可以用ACT_ID_INFO做一些树状的关联)

ACT_ID_GROUP对应实体GroupEntityImpl

ID_:跟用户组关联的唯一键

REV_:版本信息

NAME_:对group的一个描述

TYPE_:是自定义的类型,可以扩展一下业务信息

ACT_ID_MEMBERSHIP对应实体MembershipEntityImpl

USER_ID_:

GROUP_ID_:

这里主要是体现了一个简单的多对多关系。

记录一下对这几个身份数据表插入数据的操作:

  1. public class DbIdentityTest {
  2. private static final Logger LOGGER = LoggerFactory.getLogger(configDBTest.class);
  3.  
  4. @Rule
  5. public ActivitiRule activitiRule = new ActivitiRule("activiti_druid.cfg.xml");//传入自定义的mdc配置文件
  6.  
  7. @Test
  8. public void testIdentity(){
  9. //对用户和用户组的操作要先获取对应的service
  10. IdentityService identityService = activitiRule.getIdentityService();
  11. //identityService或者identity数据可以去可选的设置,在这里面默认是设置关闭掉的,
  12. // 所以需要去流程定义文件里打开
  13. // <!-- 打开用户相关的信息设置 -->
  14. // <property name="dbIdentityUsed" value="true"/>
  15. //这样数据库就会自动生成有关用户信息的表
  16.  
  17. //1.创建一个用户User,例:创建一个用户id为lll
  18. User lll = identityService.newUser("lll");
  19. //接着可以选择性的给用户设置一些属性信息
  20. lll.setFirstName("firstName");
  21. lll.setLastName("lastName");
  22. lll.setEmail("lxk@qq.com");
  23. lll.setPassword("pssword");
  24. //设置完这些用户信息,就可以对这个用户进行保存了
  25. identityService.saveUser(lll);
  26.  
  27. //2.创建一个用户组Group,例:创建一个用户组id为BossGroup
  28. Group bossGroup1 = identityService.newGroup("BossGroup1");
  29. //同样可以选择性的给用户组设置一些属性信息
  30. bossGroup1.setName("Boss");
  31. //保存这个用户组
  32. identityService.saveGroup(bossGroup1);
  33.  
  34. //3.接着就可以创建用户与组的关系了
  35. identityService.createMembership(lll.getId(),bossGroup1.getId());//createMembership这里面有两个参数,一个指定userId,一个是指定groupId
  36.  
  37. //为了体现用户与用户组多对多的关系,可以再创建一个用户
  38. User lll2 = identityService.newUser("lll2");
  39. identityService.saveUser(lll2);
  40. //同样再把这个新增的用户添加进组
  41. identityService.createMembership(lll2.getId(),bossGroup1.getId());
  42. //至此操作的使用,一共涉及到三张表:act_id_user、act_id_group、act_id_membership
  43.  
  44. //用户扩展信息表act_procdef_info的使用:(这里针对之前创建的lxk用户来使用扩展信息表,增加年龄与地址的信息)
  45. identityService.setUserInfo(lll.getId(),"age","18");//分别对应了表中USER_ID_:并联用户ID、KEY_:属性名、VALUE_;属性值 这三个字段
  46. identityService.setUserInfo(lll.getId(),"address","成都");
  47. }
  48. }

执行完数据库效果如下:

act_id_user :(这里id为主键)

act_id_group :(这里id为主键)

act_id_membership :

act_id_info :(这里id自动给的)


ACT_RU_*(运行时流程数据表)涉及到九个表:

Task:当userTask执行到此处时,会在Task表里插入数据

Variable:当启动流程、或者在流程过程中设置的一些变量信息,会存储在这张表

Identitylink:跟参与者信息相关的表,当我们设置一个用户的owner或用户的代办人、候选人的时候,都会在该表写入信息

event_subscr:流程中许多地方需要等待一个message或者singno,一个消息或者一个事件的情况下,这种监听的记录,都会存储在这张表里

job在6.0版本以后重构了一下,以前只有一个jbo表,现在有四个。

Job:一般作业表

timer_job:定时器作业表

suspended_job:当挂起的时候,暂停的作业会存放在这张表:

deadletter_job:当一个作业重复了三四次都没有成功执行下去,就会将它挪入这张表,所以说这张表的里数据是需要管理人员去关注的,需要查明原因,为什么job没有执行成功

ACT_ID_EXECUTUION对应实体ExecutionEntityImpl:

PROC_INST_ID_:流程实例ID,对应流程实例的ID的外键

BUSINESS_KEY_:业务标志

PARENT_ID_:标识这个流程实例是由哪一个流程实例启动的(如果是直接的流程实例的启动,那么这列为null)

PROC_DEF_ID_:流程定义ID  有时候会和流程执行ID是相同的

SUPERT_EXEC_:父流程实例对应的执行

ACT_ID_:流程定义节点ID  指流程定义里面执行到这个节点对应到流程定义这个节点的ID

ACT_RU_EXECUTUION对应实体ExecutionEntityImpl:

IS_ACTIVE_:是否活动的执行  0非活动,1活动

IS_CONCURRENT_:是否并行分支   0非  1是

IS_SCOPE_:是否全局流程执行 0非 1是

IS_ECENT_SCOPE_:是否激活状态

SUSPENSION_STATE:挂起状态 1正常 、2挂起

LOCK_TIME_:锁定时间

ACT_RU_TASK用户任务表对应的实体类TaskEntityImpl

EXECUTION_ID_:执行流ID

PROC_INST_ID_:流程实例ID

PROC_DEF_ID_:流程定义ID

PARENT_TASK_ID_:父任务

TASK_DEF_KEY_:任务定义ID

NAME_:任务定义名称

OWNER_:拥有人

ASSIGNEE_:代理人

DELEGATION_:委托状态  PENDING委托中,RESOLVED已处理

PRIORITY_:优先级

DUE_DATE_:过期时间

FORM_KEY_:表单标志

变量信息表

ACT_RU_VARIABLE对应实体类VariableInstanceEntityImpl:

TYPE_:变量类型(integer/string/double/json...)

NAME_:变量名 对应扩展的属性的名称   如果变量非常大的话,就会将其存进二进制的资源表并在BYTEARRAY_ID_存入这张表的ID

BYTEARRAY_ID_:资源表ID

DOUBLE_:浮点值  如果变量是浮点型就存在这

LONG_:长整型数值  如果变量是纯数字的,不管是integer还是long它都会存在这个字段下

TEXT_:文本值   如果是一个普通的文本,且它的长度没有超过一点的限制,它就会作为文本字符串存在这个字段下面

参与者信息表:当一个用户与一个流程建立关系的时候,就会在这张表里插入一条记录

比如在使用RuntimeService设置一个流程实例的owner或者signal时,都会在这张表里插入一条记录。

ACT_RU_IDENTITYLINK对应实体类IdentityLinkEntityImpl

ID_:主键

GROUP_ID_:用户组ID

TYPE_:类型assignee,candidate,owner,starter

USER_ID_:用户ID

TASK_ID_:任务ID

PROC_INST_ID_:流程实例

事件订阅信息表

ACT_RU_EVENT_SUBSCR对应实体类EventSubscriptionEntityImpl

EVENT_TYPE_:事件类型message,signal  消息、信号

EVENT_NAME_:事件名称   (事件一般都跟流程执行有一定关系)

EXECUTION_ID_:流程执行ID

PROC_INST_ID_:流程实例ID

ACTIVITY_ID_:流程定义节点ID(标识事件触发对应的流程定义节点)

CONFIGURATION_:配置(可以对流程事件做一些对应的特殊配置信息存储起来)

作业信息表:

ACT_RU_JOB对应实体类 JobEntityImpl

TYPE_:类型

LOCK_EXP_TIME_:锁定过期时间

LOCK_OWNER_:锁定节点

EXCLUSIVE_:是否唯一

RETRIES_:重试次数3

REPEAT_:重复表达式R5/PT10S

EXCEPTION_STACK_ID_:异常堆栈(资源表ID)

EXCEPTION_MSG_:异常信息

DUEDATE_:过期时间

HANDLER_TYPE_:处理器类型

HANDLER_CFG_:处理器配置

EXECUTION_ID_:流程执行表ID

记录一下对这几个表的操作:

启动一个流程会操作的表

  1. public class DbRuntimeTest {
  2. private static final Logger LOGGER = LoggerFactory.getLogger(configDBTest.class);
  3.  
  4. @Rule
  5. public ActivitiRule activitiRule = new ActivitiRule("activiti_druid.cfg.xml");//传入自定义的mdc配置文件
  6.  
  7. @Test
  8. public void testRuntime(){
  9. activitiRule.getRepositoryService()
  10. .createDeployment()
  11. .name("指定部署名称2")
  12. .addClasspathResource("second_approve.bpmn20.xml")
  13. .deploy();
  14.  
  15. Map<String, Object> variables = Maps.newHashMap();
  16. variables.put("key1","value1");
  17.  
  18. //启动流程,且在启动时,传入一些变量 值variables
  19. activitiRule.getRuntimeService()
  20. .startProcessInstanceByKey("erjishenpiliucheng",variables);
  21. }
  22. }

会操作到的表有:

1.

以及表

2.

执行到这里遇到了userTask,需要指定它去提交一个表单,所以到这里就暂停了,并且userTask里面会有一条记录。

因为前面在启动时插入了一些变量,所以变量表里面也存在一条记录

3.

上面启动一个流程的java代码里面的操作,会影响到数据表有这几个

接着记录一下给其他几个表插入数据需要如何操作:

接着上面流程暂停的步骤继续操作,指定一个owner,来让流程继续下去

  1. @Test //给参与者赋值
  2. public void testSetOwner(){
  3. TaskService taskService = activitiRule.getTaskService();
  4. //指定流程定义key,这里因为流程遇到了userTask会暂停,
  5. // 在task表里会记录是停在了哪个步骤的任务,所以
  6. // 需要查出task来给他指定一个owner来将流程继续下去
  7. Task task = taskService.createTaskQuery().processDefinitionKey("erjishenpiliucheng").singleResult();
  8. //使用taskService设置owner
  9. taskService.setOwner(task.getId(),"lxk");
  10. }

受影响的数据库表:

1.

这里可以看到这张表记录到,lxk以参与者的类型参与到了流程id  52505 的这个流程中,具体这个参与者在流程中参与了什么,有什么职责,要刷新一下task表

会发现OWNER_中同时指定了lxk这个用户。

如何让事件订阅信息表有数据呢?那就必须要让流程定义支持事件订阅,也就是说它必须支持message或者signal事件,接下来修改流程定义文件

  1. 使用my-process-message.bpmn20.xml ,代码如下
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <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/test">
  3.  
  4. <message id="messageStart" name="my-message"></message>
  5. <process id="my-process">
  6.  
  7. <startEvent id="start">
  8. <messageEventDefinition messageRef="messageStart"/>
  9. </startEvent>
  10.  
  11. <sequenceFlow id="flow1" sourceRef="start" targetRef="someTask"/>
  12. <userTask id="someTask" name="Activiti is awesome!"/>
  13. <sequenceFlow id="flow2" sourceRef="someTask" targetRef="end"/>
  14.  
  15. <endEvent id="end"/>
  16.  
  17. </process>
  18.  
  19. </definitions>

然后部署一下流程定义文件:

  1. public void testMyssage(){
  2. activitiRule.getRepositoryService()
  3. .createDeployment()
  4. .addClasspathResource("my-process-message.bpmn20.xml")
  5. .deploy();
  6. }

执行一下,会发现表:

中就有数据了:

这里EXECUTION_ID_ 与 PROC_INST_ID_为null,涉及到两种流程定义文件的区别:

一种是前者,刚才修改的那个定义文件,它的消息时间实在开始节点的位置,它可以接收一个消息 驱动流程的启动

而另一种是只有在流程开始以后,在流程的一个节点上去监听messageStart的消息,定义文件具体内容如下:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <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/test">
  3.  
  4. <message id="messageStart" name="my-message"></message>
  5. <process id="my-process">
  6.  
  7. <startEvent id="start"/>
  8.  
  9. <sequenceFlow id="flow1" sourceRef="start" targetRef="message-received"/>
  10. <intermediateCatchEvent id="message-received">
  11. <messageEventDefinition messageRef="messageStart"/>
  12. </intermediateCatchEvent>
  13. <sequenceFlow id="flow2" sourceRef="message-received" targetRef="end"/>
  14.  
  15. <endEvent id="end"/>
  16.  
  17. </process>
  18.  
  19. </definitions>

部署以后,需要再启动流程才可以看见EXECUTION_ID_ 与 PROC_INST_ID_插入数据。

接着是job表:

需要在流程定义文件中定一个 定时任务:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2.  
  3. <definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
  4. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:activiti="http://activiti.org/bpmn"
  5. xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC"
  6. xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema"
  7. expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test">
  8.  
  9. <process id="my-process">
  10.  
  11. <!--这种是自行启动流程的方式<startEvent id="start" />-->
  12. <!--定时任务来启动流程-->
  13. <startEvent id="start">
  14. <timerEventDefinition>
  15. <!-- 共执行5次,间隔为10S -->
  16. <timeCycle>R5/PT10S</timeCycle>
  17. </timerEventDefinition>
  18. </startEvent>
  19. <sequenceFlow id="flow1" sourceRef="start" targetRef="someTask" />
  20.  
  21. <userTask id="someTask" name="Activiti is awesome!" />
  22. <sequenceFlow id="flow2" sourceRef="someTask" targetRef="end" />
  23.  
  24. <endEvent id="end" />
  25.  
  26. </process>
  27.  
  28. </definitions>

启动流程:

  1. public void testJob() throws InterruptedException {
  2. activitiRule.getRepositoryService()
  3. .createDeployment()
  4. .addClasspathResource("my-process_job.bpmn20.xml")
  5. .deploy();
  6.  
  7. Thread.sleep(1000*30L);
  8. }

观察数据库 

插入了数据:



ACT_HI_*(历史流程数据表)涉及到九个表:

事件日志表比较特殊,只能插入与删除,无法修改

这里面有几个单表:

主要是跟TASK相关的

附件表与评论表:

ACT_HI_ATTACHMENT:在用户任务的处理过程中,可以提交一些附件

ACT_HI_COMMENT:或者添加一些评论

一般都是有需求时,对它们单独进行编辑,这两个表没有对应的运行时表,因为在运行的操作的过程中,提交的内容直接就把它作为历史记录存储起来

ACT_HI_PROCINST对应的实体类HistoricProcessInstanceEntityImpl

PROC_INST_ID_:流程实例ID

BUSINESS_KEY_:业务ID

PROC_DEF_ID_:流程定义ID

START_TIME_:开始时间

END_TIME_:结束时间

DURATION_:执行时长

START_USER_ID_:流程发起人

START_ACT_ID_:开始节点ID

END_ACT_ID_:结束节点ID

SUPER_PROCESS_INSTANCE_ID_:父流程实例

DELETE_REASON_:删除原因

TENANT_ID_:多租户

记录一下操作实例:

  1. public class DbHistoryTest {
  2. private static final Logger LOGGER = LoggerFactory.getLogger(configDBTest.class);
  3.  
  4. @Rule
  5. public ActivitiRule activitiRule = new ActivitiRule("activiti_druid.cfg.xml");//传入自定义的mdc配置文件
  6.  
  7. @Test
  8. public void testHistory(){
  9. //自动
  10. activitiRule.getRepositoryService()
  11. .createDeployment()
  12. .name("指定部署名称")
  13. .addClasspathResource("my-process.bpmn20.xml");
  14.  
  15. RuntimeService runtimeService = activitiRule.getRuntimeService();
  16.  
  17. Map<String, Object> variables = Maps.newHashMap();
  18. variables.put("key0","value0");
  19. variables.put("key1","value1");
  20. variables.put("key2","value2");
  21.  
  22. ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("my-process", variables);
  23. //启动完以后获取流程实例ID,修改变量
  24. runtimeService.setVariable(processInstance.getId(),"key1","value1");
  25.  
  26. //获取TaskService,然后获取到当前唯一需要执行的task
  27. TaskService taskService = activitiRule.getTaskService();
  28.  
  29. //获取task是要演示一下参与者里面是否有添加一条记录
  30. Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
  31.  
  32. //给当前task指定一个owner
  33. taskService.setOwner(task.getId(),"lxk");
  34. //同时上传一些附件
  35. taskService.createAttachment("url",task.getId(),processInstance.getId(),"附件","附件描述","/url/test.png");
  36. //同时再添加一些评论
  37. taskService.addComment(task.getId(),task.getProcessInstanceId(),"评论1");
  38. taskService.addComment(task.getId(),task.getProcessInstanceId(),"评论2");
  39.  
  40. //完成这些操作以后,可以通过formService来将表单提交上去,也可以用taskservice来提交
  41. Map<String, String> properties = Maps.newHashMap();
  42. properties.put("key2","value2_1覆盖");
  43. properties.put("key3","value3_1");
  44. activitiRule.getFormService().submitTaskFormData(task.getId(),properties);
  45. }
  46. }

执行效果:

表:

表:

表:

表:

附件表:

评论表:

Acitiviti数据库表设计(学习笔记)的更多相关文章

  1. DirectX 9 UI三种设计学习笔记:文章4章Introducing DirectInput+文章5章Wrapping Direct3D

           本文从哈利_创.转载请注明出处.有问题欢迎联系本人!        邮箱:2024958085@qq.com 上一期的地址: DX 9 UI设计学习笔记之二 第4章 Introducin ...

  2. 数据库表设计时一对一关系存在的必要性 数据库一对一、一对多、多对多设计 面试逻辑题3.31 sql server 查询某个表被哪些存储过程调用 DataTable根据字段去重 .Net Core Cors中间件解析 分析MySQL中哪些情况下数据库索引会失效

    数据库表设计时一对一关系存在的必要性 2017年07月24日 10:01:07 阅读数:694 在表设计过程中,我无意中觉得一对一关系觉得好没道理,直接放到一张表中不就可以了吗?真是说,网上信息什么都 ...

  3. Oracle数据库表设计时的注意事项

    表是Oracle数据库中最基本的对象之一.万丈高楼从平地起,这个基础对象对于数据库来说,非常重要.因为其设计是否合理,直接跟数据库的性能相关.从Oracle数据库菜鸟到数据库专家这个过程中,在表设计与 ...

  4. Innodb IO优化 — 数据库表设计 转

    数据库表设计这块学问比较多,我这里单从互联网角度出发同时结合Innodb的特性给出一些设计方法供大家参考.本文构建大概分两分部分:Innodb的特性及设计中如何利用这种特性. Innodb特性: In ...

  5. SQL SERVER 数据库表同步复制 笔记

    SQL SERVER 数据库表同步复制 笔记 同步复制可运行在不同版本的SQL Server服务之间 环境模拟需要两台数据库192.168.1.1(发布),192.168.1.10(订阅) 1.在发布 ...

  6. Flas-SQLAchemy数据库操作使用学习笔记

    Flas-SQLAchemy数据库操作使用学习笔记 Flask-SQLALchemy 是一个给你的应用添加 SQLALchemy 支持的 Flask 扩展.SQLALchemy 是Python语言的S ...

  7. springmvc 项目完整示例01 需求与数据库表设计 简单的springmvc应用实例 web项目

    一个简单的用户登录系统 用户有账号密码,登录ip,登录时间 打开登录页面,输入用户名密码 登录日志,可以记录登陆的时间,登陆的ip 成功登陆了的话,就更新用户的最后登入时间和ip,同时记录一条登录记录 ...

  8. loadrunner 场景设计-学习笔记之性能误区

    场景设计-学习笔记之性能误区 by:授客 QQ:1033553122 场景假设: 每个事务仅包含一次请求,执行10000个并发用户数 性能误区: 每秒并发用户数=每秒向服务器提交请求数 详细解答: 每 ...

  9. 【Redis数据库】命令学习笔记——发布订阅、事务、脚本、连接等命令汇总

    本篇基于redis 4.0.11版本,学习发布订阅.事务.脚本.连接的相关命令. Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息. 序号 ...

随机推荐

  1. springboot~Mongodb的集成与使用

    说说springboot与大叔lind.ddd的渊源 Mongodb在Lind.DDD中被二次封装过(大叔的.net和.net core),将它当成是一种仓储来使用,对于开发人员来说只公开curd几个 ...

  2. SLAM+语音机器人DIY系列:(四)差分底盘设计——2.stm32主控软件设计

    摘要 运动底盘是移动机器人的重要组成部分,不像激光雷达.IMU.麦克风.音响.摄像头这些通用部件可以直接买到,很难买到通用的底盘.一方面是因为底盘的尺寸结构和参数是要与具体机器人匹配的:另一方面是因为 ...

  3. Lumen框架-错误&日志

    介绍 当你开始一个新的Lumen项目的时候,错误和异常功能,已经在框架中注入了.此外,Lumen还集成了Monolog日志函数,支持和提供多种强大的日志处理功能. 配置 错误详情 大量的错误信息在你的 ...

  4. Jetson Nano Developer Kit

    The Jetson Nano Developer Kit is an AI computer for learning and for making. ​ 一个推理框架,用于部署模型到嵌入式设备. ...

  5. 从零开始学安全(四十四)●TCP三次握手四次挥手

    wireshark:Beyond Compare是一个网络封包分析软件.网络封包分析软件的功能是撷取网络封包,并尽可能显示出最为详细的网络封包资料.Wireshark使用WinPCAP作为接口,直接与 ...

  6. Redis分布式队列和缓存更新

    原文链接:https://www.cnblogs.com/hua66/p/9600085.html 在使用Redis中,我们可能会遇到以下场景: 例如: 某用户向服务器中发送一个请求,服务器将用户请求 ...

  7. nginx系列9:HTTP反向代理请求处理流程

    HTTP反向代理请求处理流程 如下图:

  8. tablednd onDrap 方法不调用

    场景 使用 tablednd 插件时,onDrap 方法不调用 解决 给tr标签加 id 属性

  9. 对于python爬虫urllib库的一些理解(抽空更新)

    urllib库是Python中一个最基本的网络请求库.可以模拟浏览器的行为,向指定的服务器发送一个请求,并可以保存服务器返回的数据. urlopen函数: 在Python3的urllib库中,所有和网 ...

  10. SAP MM 明明有需求,为啥MRP RUN后没有PR单据产生?

    SAP MM 明明有需求,为啥MRP RUN后没有PR单据产生? 用户报了一个问题说,对于物料号42011222的采购单 4500000156建好了,为啥PR没有自动生成 . 我们检查了物料的MRP ...