Springboot整合squirrel-foundation状态机

article/2025/9/11 1:02:55

目录

一. 快速入门

1 . maven

2 . 快速开始

3 . Fluent Api 

4 . 状态机四要素

5 . 状态机构建器

6 . 状态机转换操作(代码配置方式)

7 . 状态机转换操作(注解声明方式)

8 . 上下文不敏感状态机

二 : 使用注意事项

P1 :  异常 :  StateMachineBuilderImpl cannot find Initial state 'B' in state machine

P2 :  转换异常 : 


上一篇文章介绍了 状态机介绍以及常见种类对比  。本篇主要介绍一下项目中如何使用squirrel-foundation的一些细节以及如何与spring进行集成的流程。

状态机(有限状态自动机 FSM)介绍_黄嚯嚯-CSDN博客状态机概念, 为什么要使用状态机https://blog.csdn.net/qq_42543063/article/details/119111658 阅读过程中如有介绍不全的位置  , 也可以留言 , 或者参考官方文档自行分析   squirrel-foundation | Squirrel State Machinesquirrel-foundation provided an easy use, type safe and highly extensible state machine implementation for Java.http://hekailiang.github.io/squirrel/

一. 快速入门

1 . maven

squirrel-foundation 的最新包 已经部署到了maven的中央仓库,所以只需要在pom.xml中添加如下依赖即可。

目前最新版本 

<dependency><groupId>org.squirrelframework</groupId><artifactId>squirrel-foundation</artifactId><version>0.3.8</version>
</dependency>

该状态机引擎的maven有可能会引起一下jar 冲突 , 导致项目启动Or 执行异常 

        <!--状态机引擎--><dependency><groupId>org.squirrelframework</groupId><artifactId>squirrel-foundation</artifactId><version>0.3.8</version><!-- 可能会出现冲的的相关jar 如果项目中没有引入一下几类可忽略--> <exclusions><exclusion><artifactId>log4j</artifactId><groupId>log4j</groupId></exclusion><exclusion><artifactId>slf4j-log4j12</artifactId><groupId>org.slf4j</groupId></exclusion><exclusion><artifactId>guava</artifactId><groupId>com.google.guava</groupId></exclusion></exclusions></dependency>

2 . 快速开始

squirrel-foundation官方文档提供了一个小demo , 相对来说比较简洁, 非常适合初学者 . , 一下这个quickStartSample 是可以直接运行的 , 可以先动手尝试 , 细节点请继续往下看

public class QuickStartSample {// 1. 定义一个事件枚举类enum FSMEvent {ToA, ToB, ToC, ToD}// 2. 定义一个状态机本体@StateMachineParameters(stateType=String.class, eventType=FSMEvent.class, contextType=Integer.class)static class StateMachineSample extends AbstractStateMachine<MyStateMachine , FSMState , FSMEvent , Integer> {protected void fromAToB(String from, String to, FSMEvent event, Integer context) {System.out.println("Transition from '"+from+"' to '"+to+"' on event '"+event+"' with context '"+context+"'.");}protected void ontoB(String from, String to, FSMEvent event, Integer context) {System.out.println("Entry State \'"+to+"\'.");}}public static void main(String[] args) {// 3. 构建转换builderStateMachineBuilder<MyStateMachine, FSMState, FSMEvent, Integer> builder= StateMachineBuilderFactory.create(MyStateMachine.class, FSMState.class,FSMEvent.class, Integer.class);builder.externalTransition().from("A").to("B").on(FSMEvent.ToB).callMethod("fromAToB");builder.onEntry("B").callMethod("ontoB");// 4. 使用状态机MyStateMachine fsm = builder.newStateMachine("A");// 5 . 驱动状态fsm.fire(FSMEvent.ToB, 10);System.out.println("Current state is "+fsm.getCurrentState());}
}

首先 squirrel-foundation 支持 fluent API 和声明方式来声明状态机,并且还允许用户以直接的方式定义操作方法。

但是 , 官方文档并没有介绍 fluent API 这种编码方式 

3 . Fluent Api 

quickStartSample 中体现在

builder.externalTransition().from("A").to("B").on(FSMEvent.ToB).callMethod("fromAToB");

在编写软件库的时候,我们有两种选择。一种是提供Command-Query API,另一种是Fluent Interfaces。比如Mockito的API when(mockedList.get(anyInt())).thenReturn("element")就是一种典型连贯接口的用法。

Fluent的这种连贯性带来的可读性和可理解的提升,其本质不仅仅是在提供API,更是一种领域语言,是一种Internal DSL。

比如Mockito的API when(mockedList.get(anyInt())).thenReturn("element")就非常适合用Fluent的形式,实际上,它也是单元测试这个特定领域的DSL。

这里需要注意的是,连贯接口不仅仅可以提供类似于method chaining和builder模式的方法级联调用,比如OkHttpClient中的Builder

他更重要的作用是,限定方法调用的顺序。比如,在构建状态机的时候,我们只有在调用了from方法后,才能调用to方法,Builder模式没有这个功能。

OkHttpClient.Builder builder=new OkHttpClient.Builder();OkHttpClient okHttpClient=builder.readTimeout(5*1000, TimeUnit.SECONDS).writeTimeout(5*1000, TimeUnit.SECONDS).connectTimeout(5*1000, TimeUnit.SECONDS).build();

4 . 状态机四要素

QuickStartSample 中体现在如下 

@StateMachineParameters(stateType=String.class, eventType=FSMEvent.class, contextType=Integer.class)static class StateMachineSample extends AbstractStateMachine<MyStateMachine , FSMState , FSMEvent , Integer>

StateMachine接口采用四个泛型类型参数。StateMachine<T, S, E, C> ,

ps : 要是想看这几个状态的可以向上找下  AbstractStateMachine 关系如下 👇 

MyStateMachine extends AbstractUntypedStateMachine

AbstractUntypedStateMachine extends AbstractStateMachine

  • 代表已实现状态机的类型 ,, 也就是状态机本体。
  • 代表实现状态的类型 。
  • 代表已实现事件的类型。
  • 代表已实现的外部上下文的类型。

5 . 状态机构建器

QuickStartSample 中体现在如下 

StateMachineBuilder<MyStateMachine, MyState, MyEvent, MyContext> builder =StateMachineBuilderFactory.create(MyStateMachine.class, MyState.class, MyEvent.class, MyContext.class);		

为了创建状态机,用户需要先创建状态机构建器。 

  • 状态机构建器用于生成状态机的相关状态转换定义。StateMachineBuilder 可以由 StateMachineBuilderFactory 创建 。ps: 后续博主会更新相关使用 , 届时将自定义 StateMachineBuilderFactory
  • StateMachineBuilder 由用于构建状态之间的转换的 *TransitionBuilder (InternalTransitionBuilder / LocalTransitionBuilder / ExternalTransitionBuilder) 和用于构建进入或退出状态期间动作的 EntryExitActionBuilder 。
  • 内部状态是在转换创建或状态操作期间隐式构建的。
  • 由同一个状态机构建器创建的所有状态机实例共享相同的内存。
  • 状态机构建器以惰性方式生成状态机定义。当构建器创建第一个状态机实例时,将生成状态机定义,首次比较消耗时间。但是在生成状态机定义之后,接下来的状态机实例创建会快很多。一般来说,状态机构建器应该尽可能地重用。

6 . 状态机转换操作(代码配置方式)

  • 一个状态转换至另一个状态
        // 事件 ToB 触发条件转换由 A -> B  , 调用执行方法  formToB  以此类推builder.externalTransition().from(FSMState.A).to(FSMState.B).on(FSMEvent.GoToB).callMethod("fromAGoToB");//使用状态机MyStateMachine machine = builder.newStateMachine(FSMState.A);machine.fire(FSMEvent.GoToB, 22);
  •   n个状态中任意一个状态转换至另一个状态 ( 反之(调转一下fromAmong ) 一个状态转换至n个状态中任意一个状态 
        // 事件 GoToD 触发条件转换由 A Or B Or C  ->  D  , 调用执行方法  transitFromAnyToDOnGoToD  以此类推builder.externalTransitions().fromAmong(FSMState.A,FSMState.B,FSMState.C).to(FSMState.D).on(FSMEvent.GoToD).callMethod("transitFromAnyToDOnGoToD");//使用状态机 正常状态转换BMyStateMachine machine = builder.newStateMachine(FSMState.B);machine.fire(FSMEvent.GoToD, 77);
  •  多种状态任意转换  , 多种事件  之间转换也可以写成如下这种方式 配置

注意事项详见文章末尾  P1 !!!!!!!!!!!!!!!!!

        // 构建状态机转换BuilderStateMachineBuilder<MyStateMachine, FSMState, FSMEvent, Integer> builder= StateMachineBuilderFactory.create(MyStateMachine.class, FSMState.class,FSMEvent.class, Integer.class);// 定义转换事件builder.externalTransition().from(FSMState.A).to(FSMState.B).on(FSMEvent.GoToB).callMethod("fromAGoToB");builder.externalTransition().from(FSMState.A).to(FSMState.C).on(FSMEvent.GoToC).callMethod("fromAGoToC");builder.externalTransition().from(FSMState.B).to(FSMState.C).on(FSMEvent.GoToC).callMethod("fromBGoToC");// A -> 被任意事件触发 -> 到任意状态 调用ssss 函数builder.transit().from(FSMState.A).toAny().onAny().callMethod("ssss");// 任意事件触发 -> 任意状态 -> B 调用函数builder.transit().fromAny().to(FSMState.C).onAny().callMethod("aaaaa");// 当 , 当前状态时 B 时候 , 触发执行方法  ontoBbuilder.onEntry(FSMState.B).callMethod("ontoB");builder.onEntry(FSMState.C).callMethod("ontoC");//使用状态机 正常状态转换MyStateMachine machine = builder.newStateMachine(FSMState.B);machine.fire(FSMEvent.GoToC, 22);System.out.println("当前状态是 : " + machine.getCurrentState());
  • 当状态进入某个状态 ( 若要触发onEntry() , 就得配置相对应的进入操作 , 例如要进入 状态 B 时候有动作 , 就得构建状态装换动作 , 来完成
         // 事件 ToB 触发条件转换由 A -> B  , 调用执行方法  formToB  以此类推builder.externalTransition().from(FSMState.A).to(FSMState.B).on(FSMEvent.GoToB).callMethod("fromAGoToB");builder.onEntry(FSMState.B).callMethod("ontoB");//使用状态机MyStateMachine machine = builder.newStateMachine(FSMState.A);machine.fire(FSMEvent.GoToB, 22);
  • 当状态退出某个状态( 若要触发 onExit() , 注意事项等同于 触发onEntry()
        // 事件 GoToD 触发条件转换由 A Or B Or C  ->  D  , 调用执行方法  transitFromAnyToDOnGoToD  以此类推builder.externalTransitions().fromAmong(FSMState.A,FSMState.B,FSMState.C).to(FSMState.D).on(FSMEvent.GoToD).callMethod("transitFromAnyToDOnGoToD");builder.onExit(FSMState.A).callMethod("exit");//使用状态机 正常状态转换BMyStateMachine machine = builder.newStateMachine(FSMState.A);machine.fire(FSMEvent.GoToD, 77);

7 . 状态机转换操作(注解声明方式)


// 定义状态机
@States({@State(name = "A" , entryCallMethod = "ontoA" , exitCallMethod = "exitA")
})
@Transitions({@Transit(from = "A" , to = "B" , on = "GoToB" , callMethod = "fromAGoToB"),@Transit(from = "A" , to = "C" , on = "GoToC" , callMethod = "fromAGoToB")
})
@SuppressWarnings("all")
@StateMachineParameters(stateType = FSMState.class, eventType = FSMEvent.class, contextType = Integer.class)
public class MyAnnotationStateMachine extends AbstractStateMachine<MyAnnotationStateMachine, FSMState , FSMEvent , Integer> {
  • 配置状态进入或退出

entryCallMethod : 是当状态进入时的操作  ,   exitCallMethod = 是当状态推出时的操作

@States({@State(name = "A" , entryCallMethod = "ontoA" , exitCallMethod = "exitA")
})
  • 配置状态转换操作

状态因为触发事件 (on)  从  (from)  到  ( to)   ,  调用方法 (callMethod)     

@Transitions({@Transit(from = "A" , to = "B" , on = "GoToB" , callMethod = "fromAGoToB"),@Transit(from = "A" , to = "C" , on = "GoToC" , callMethod = "fromAGoToB")
})
  • 多状态任意转换

注意事项详见文章末尾  P1 !!!!!!!!!!!!!!!!!

// 最后一条配置的是  GoToC 事件触发的任意状态转换至C都会触发 fromAnyToC
@Transitions({@Transit(from = "A", to = "B", on = "GoToB", callMethod = "fromAGoToB"),@Transit(from = "A", to = "C", on = "GoToC", callMethod = "fromAGoToC"),@Transit(from = "B", to = "C", on = "GoToC", callMethod = "fromAGoToC"),@Transit(from = "*", to = "C", on = "GoToC", callMethod = "fromAnyToC")
})

8 . 上下文不敏感状态机

有时状态转换不关心上下文,这意味着转换大多仅由事件决定。对于这种情况,用户可以使用上下文不敏感状态机来简化方法调用参数。
声明上下文不敏感状态机非常简单。用户只需要在状态机实现类上添加注解@ContextInsensitive。之后,可以忽略转换方法参数列表中的上下文参数。例如

@ContextInsensitivepublic class ATMStateMachine extends AbstractStateMachine<ATMStateMachine, ATMState, String, Void> {// 这里不再需要添加上下文参数public void transitFromIdleToLoadingOnConnected(ATMState from, ATMState to, String event) {...}public void entryLoading(ATMState from, ATMState to, String event) {...}
}

二 : 使用注意事项

P1 :  异常 :  StateMachineBuilderImpl cannot find Initial state 'B' in state machine

1 . 这是最初模样 ,  是正常可执行的.

    private static void test1(){// 构建状态机转换BuilderStateMachineBuilder<MyStateMachine, FSMState, FSMEvent, Integer> builder= StateMachineBuilderFactory.create(MyStateMachine.class, FSMState.class,FSMEvent.class, Integer.class);// 事件 ToB 触发条件转换由 A -> B  , 调用执行方法  formToB  以此类推builder.externalTransition().from(FSMState.A).to(FSMState.B).on(FSMEvent.GoToB).callMethod("fromAGoToB");builder.externalTransition().from(FSMState.A).to(FSMState.C).on(FSMEvent.GoToC).callMethod("fromAGoToC");builder.externalTransition().from(FSMState.B).to(FSMState.C).on(FSMEvent.GoToC).callMethod("fromBGoToC");builder.transit().fromAny().to(FSMState.C).onAny().callMethod("aaaaa");builder.transit().from(FSMState.A).toAny().onAny().callMethod("ssss");// 当 , 当前状态时 B 时候 , 触发执行方法  ontoBbuilder.onEntry(FSMState.B).callMethod("ontoB");builder.onEntry(FSMState.C).callMethod("ontoC");//使用状态机 正常状态转换MyStateMachine machine = builder.newStateMachine(FSMState.B);machine.fire(FSMEvent.GoToC, 22);System.out.println("当前状态是 : " + machine.getCurrentState());}

2 . 接下来稍作修改 注释掉 一部分状态转换的定义 , 可进入某个装态的定义 ,  只保留 两个任意状态装换的定义  

    private static void test1(){// 构建状态机转换BuilderStateMachineBuilder<MyStateMachine, FSMState, FSMEvent, Integer> builder= StateMachineBuilderFactory.create(MyStateMachine.class, FSMState.class,FSMEvent.class, Integer.class);// 事件 ToB 触发条件转换由 A -> B  , 调用执行方法  formToB  以此类推//builder.externalTransition().from(FSMState.A).to(FSMState.B).on(FSMEvent.GoToB).callMethod("fromAGoToB");//builder.externalTransition().from(FSMState.A).to(FSMState.C).on(FSMEvent.GoToC).callMethod("fromAGoToC");//builder.externalTransition().from(FSMState.B).to(FSMState.C).on(FSMEvent.GoToC).callMethod("fromBGoToC");builder.transit().fromAny().to(FSMState.C).onAny().callMethod("aaaaa");builder.transit().from(FSMState.A).toAny().onAny().callMethod("ssss");// 当 , 当前状态时 B 时候 , 触发执行方法  ontoB//builder.onEntry(FSMState.B).callMethod("ontoB");//builder.onEntry(FSMState.C).callMethod("ontoC");//使用状态机 正常状态转换MyStateMachine machine = builder.newStateMachine(FSMState.B);machine.fire(FSMEvent.GoToC, 22);System.out.println("当前状态是 : " + machine.getCurrentState());}

3 . 在执行之后就直接抛了如下异常  , 说是找不到A这个状态 没法初始化状态机 

Exception in thread "main" java.lang.IllegalArgumentException: class org.squirrelframework.foundation.fsm.impl.StateMachineBuilderImpl cannot find Initial state 'B' in state machine.at org.squirrelframework.foundation.fsm.impl.StateMachineBuilderImpl.newStateMachine(StateMachineBuilderImpl.java:708)at org.squirrelframework.foundation.fsm.impl.StateMachineBuilderImpl.newStateMachine(StateMachineBuilderImpl.java:700)at org.squirrelframework.foundation.fsm.impl.StateMachineBuilderImpl.newStateMachine(StateMachineBuilderImpl.java:695)at com.ko.assy.squirrel.statemachine.simple.QuickStartSample.test1(QuickStartSample.java:36)at com.ko.assy.squirrel.statemachine.simple.QuickStartSample.main(QuickStartSample.java:16)

4 . 为了找出问题所在, 逐步放开 在 p2 上面注释的代码  , 做修改如下  , 

        // 注意此处放开了注释  , 但只是放开了有关 进入状态C 的定义  ,  并没有放开 B 的定义 , 结果执行仍旧报错 
        builder.onEntry(FSMState.C).callMethod("ontoC");

接下来放开 //builder.onEntry(FSMState.B).callMethod("ontoB");  ,  在这里面定义了有关进入B 的相关操作  , 执行如下

//使用状态机 正常状态转换   B -> C   按以上的  builder.transit().fromAny().to(FSMState.C).onAny().callMethod("aaaaa"); 这一句理解的话 , 应该会触发的 , 可实际并没有触发
MyStateMachine machine = builder.newStateMachine(FSMState.B);
machine.fire(FSMEvent.GoToC, 22);

结论   ::::   原因是因为只定义了 进入B  和 进入 C ,  虽然有了这个定义,  但是仍旧缺失  初始值 是 B ,  触发事件是 GotoC 的定义  

所以只需要放开上面的这一句即可 , 有操作 就得有定义 !!

builder.externalTransition().from(FSMState.B).to(FSMState.C).on(FSMEvent.GoToC).callMethod("fromBGoToC");

P2转换异常 : 

当状态转换过程中发生异常时,执行的动作列表将被中止,状态机将进入错误状态,这意味着状态机实例不能再处理事件。如果用户继续向状态机实例触发事件,则会抛出 IllegalStateException。
过渡阶段发生的所有异常,包括动作执行和外部侦听器调用,都将被包装到 TransitionException(未检查异常)中。目前,默认的异常处理策略简单粗暴,只是继续抛出异常,参见 AbstractStateMachine.afterTransitionCausedException 方法。

 protected void afterTransitionCausedException(...) { throw e; }

如果可以从该异常中恢复状态机,用户可以扩展 afterTransitionCausedException 方法,并在该方法中添加相应的恢复逻辑。最后不要忘记将状态机状态设置回正常。例如

  @Overrideprotected void afterTransitionCausedException(Object fromState, Object toState, Object event, Object context) {Throwable targeException = getLastException().getTargetException();// recover from IllegalArgumentException thrown out from state 'A' to 'B' caused by event 'ToB'if(targeException instanceof IllegalArgumentException && fromState.equals("A") && toState.equals("B") && event.equals("ToB")) {// do some error clean up job here// ...// after recovered from this exception, reset the state machine status back to normalsetStatus(StateMachineStatus.IDLE);} else if(...) {// recover from other exception ...} else {super.afterTransitionCausedException(fromState, toState, event, context);}}

 PS:   以上是入门级的 快速开始demo  ,  后续博主会更新自定义注册工厂  以及自定义可扩展的功能 

Springboot整合squirrel-foundation状态机自定义可扩展_黄嚯嚯-CSDN博客Springboot整合squirrel-foundation状态机https://blog.csdn.net/qq_42543063/article/details/120995893


http://chatgpt.dhexx.cn/article/UWX3N4Qg.shtml

相关文章

Hive的客户端界面工具–SQuirrel SQL Client--详细安装以及连接Hive过程

SQuirrel SQL Client是一款支持Hive的可视化工具&#xff0c;是市面上少数支持Hive中比较好用的&#xff0c;看下如何安装使用吧&#xff0c;下面是非常详细的安装过程。 1.下载客户端 SQuirrel SQL Client的官网及下载地址为&#xff1a;http://squirrel-sql.sourceforge.ne…

Linux安装SQuirreL SQL Client

环境和准备 操作系统&#xff1a; Ubuntu 20.04SQuirreL&#xff1a; squirrel-sql-snapshot-20220326_1238-standard.jarDb2 driver&#xff1a; db2jcc4.jardb2jcc_license_cu.jar MySQL driver&#xff1a; mysql-connector-java-8.0.27.jar 下载和安装 首先下载SQuirreL…

智能优化算法之松鼠算法(Squirrel search algorithm)

文章目录 背景Squirrel search algorithm(SSA)SSARandom initialization&#xff08;随机初始化&#xff09;Fitness evaluation&#xff08;适应值评价&#xff09;Sorting, declaration and random selection&#xff08;排序、声明和随机选择&#xff09;Generate new locat…

electron打包遇到 Making for target: squirrel - On platform: win32 - For arch: x64错误

上面横线处是出现错误的位置。报错的原因如下&#xff1a; 1、package.json的“author”和“description”在打包时是必填内容&#xff0c;随便填些内容即可打包成功。 2、和项目的绝对路径有关&#xff0c;项目的绝对路径不能出现中文&#xff0c;否则在红线处会报错。

WPF 使用Squirrel自动更新应用

前言 本文简单的介绍了如何使用 Squirrel 来为 WPF 客户端 进行自动检查更新。 Squirrel git 地址 &#xff1a;http:// https://github.com/Squirrel/Squirrel.Windows 本文使用了 Visual Studio 2022 进行演示讲解。 参考英文博客&#xff1a; https://intellitect.com/d…

SQuirrel SQL Client的安装

如果您的工作要求您在一天之中连接许多不同的数据库 &#xff08;oracle、DB2、mysql、postgresql、Sql Server等等&#xff09;&#xff0c;或者你经常需要在多个不同种类的数据库之间进行数导入导出。那么SQuirreL SQL Client 将会是比较理想的数据库客户端链接工具。 简单介…

数据库管理工具——SQuirreL SQL Client使用入门

如果您的工作要求您在一天之中连接许多不同的数据库 &#xff08;oracle、DB2、mysql、postgresql、Sql Server等等&#xff09;&#xff0c;或者你经常需要在多个不同种类的数据库之间进行数导入导出。那么SQuirreL SQL Client 将会是比较理想的数据库客户端链接工具。 简单介…

SQuirrel连接hive配置

1. 简介 最近由于大数据部门相关同事离职&#xff0c;不得不研究一下大数据相关组件&#xff0c;今天成功安装配置Hive&#xff0c;简单记录&#xff0c;一是为了加深印象&#xff0c;二是为以后备用&#xff0c;三是为大家提供参考&#xff0c;避免少踩坑。 在Hive的官网上…

FSM——squirrel状态机使用

FSM——squirrel状态机使用 1 FSM介绍 1.1 概念 FSM&#xff08;finite state machine&#xff09;:有限状态机 是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型。核心内容&#xff1a;有限个状态、通过外部操作引起状态的转移。用来对状态的流转进行解耦&a…

Squirrel SQL客户端使用图解

一、Squirrel简介 Squirrel是一个连接数据库的客户端工具&#xff0c;一般支持JDBC的数据库都可以用它来简介&#xff0c;如连接MySQL。 二、安装准备 下载jar包&#xff1a;squirrel-sql-3.7.1-standard.jar 三、安装 ①进入squirrel-sql-3.7.1-standard.jar文件所在的目录…

完成GitHub上squirrel 的运行(数据库的模糊测试)

文章目录 一、squirrel的介绍squirrel链接建议下载Ubuntu 18.04编译安装clang/llvm&#xff08;建议9.0以上&#xff09;将squirrel的文件下载到Ubuntu上下载docker&#xff08;建议按照dockerfile步骤直接在外部搭建环境&#xff09;Dockerfile创建镜像按照dockfile搭建时时有…

连接HiveServer2的图形化工具SQuirrel和Dbeaver

文章目录 SQuirrel SQL Client简介视频演示安装SQuirrel SQL Client启动hdfs和hiveserver2配置SQuirrel SQL Client使用SQuirrel SQL Client访问hive使用Cloudera提供的hive连接驱动进行连接Dbeaver的安装及使用 本文介绍的工具可以通过下面链接下载&#xff1a; 链接&#xff…

squirrel校园二手交易平台

##squirrel校园二手交易平台 &#xff08;适合寻找SSM项目练手的你。&#xff09; 问题汇总&#xff1a; &#xff08;朋友毕设用到了这个二手平台&#xff0c;他自己把后台优化了&#xff0c;我又帮忙实现了一部分功能&#xff0c;只能做到这里了。有兴趣的&#xff0c;自行优…

squirrel sql 使用

前置 安装jdk&#xff08;1.8版本即可&#xff09; 1、官网下载squirrel sql client jar https://sourceforge.net/projects/squirrel-sql/ 2 运行java -jar squirrel-sql-3.6-standard.jar安装 jar包 注意3.0的版本要JDK1.6以上 这里可以改安装目录 这里可以选择插件&#…

[squirrel使用]--Windows安装详解

squirrel在windows下的安装文档 一&#xff0e;下载安装 从网址http://www.squirrelsql.org/下载相应版本的squirrel的安装jar包&#xff0c;比如下载squirrel-sql-3.7-standard.jar双击安装&#xff0c;出现如下安装界面&#xff0c;下一步开始安装 二&#xff0e;配置连接p…

Squirrel状态机-从原理探究到最佳实践

作者&#xff1a;京东物流 郑朋辉 1 简介 Squirrel状态机是一种用来进行对象行为建模的工具&#xff0c;主要描述对象在它的生命周期内所经历的状态&#xff0c;以及如何响应来自外界的各种事件。比如订单的创建、已支付、发货、收获、取消等等状态、状态之间的控制、触发事件…

squirrel(松鼠)状态机的介绍及使用

squirrel&#xff08;松鼠&#xff09;状态机 依赖 <dependency><groupId>org.squirrelframework</groupId><artifactId>squirrel-foundation</artifactId><version>0.3.8</version> </dependency>状态机描述 参考&#xf…

将图片转换为base64编码

1、base64编码简介 Base64是一种可逆的编码方式&#xff0c;简单来讲就是一种将64个Ascii字符来表示成二进制数据的方法。主要用于将不可打印的字符转换成可打印字符&#xff0c;或者简单的说将二进制数据编码成Ascii字符。Base64是网络上最常用的传输8bit字节数据的编码方式之…

前端理解base64

一、背景&#xff1a;ascii码 字符>二进制 计算机中所有数据的存储都是以二进制模式&#xff0c;比如想要存储abcd需将其转化为二进制&#xff0c;具体用哪些二进制来表示哪个符号*&#xff0c;有一个统一的编码规则&#xff0c;这就是ascii。 ASCII 码使用指定的7 位或8…

Web 图片Base64编码

转载自: 【前端攻略】&#xff1a;玩转图片Base64编码 引言   图片处理在前端工作中可谓占据了很重要的一壁江山。而图片的 base64 编码可能相对一些人而言比较陌生&#xff0c;本文不是从纯技术的角度去讨论图片的 base64 编码。标题略大&#xff0c;不过只是希望通过一些…