Easy Rules规则引擎(2-细节篇)

目录

  • 一、序言
  • 二、规则引擎参数配置实例
    • 1、skipOnFirstAppliedRules示例
      • (1) FizzRule
      • (2) BuzzRule
      • (3) FizzBuzzRule
      • (4) NonFizzBuzzRule
      • (5) FizzBuzzRulesLauncher
    • 2、skipOnFirstNonTriggeredRule示例
    • 3、skipOnFirstFailedRule示例
  • 三、组合规则
    • 1、UnitRuleGroup组合规则
    • 2、ActivationRuleGroup组合规则
    • 3、ConditionalRuleGroup组合规则

一、序言

在 Easy Rules规则引擎(1-基础篇) 中我们已经简单介绍了Easy Rules规则引擎的使用示例,这节我们详解介绍一下规则引擎的相关参数配置实例还有组合规则。


二、规则引擎参数配置实例

Easy Rules规则引擎支持下面参数配置:

参数名称参数类型必选默认值
rulePriorityThresholdintInteger.MAX_VALUE
skipOnFirstAppliedRulebooleanfalse
skipOnFirstFailedRulebooleanfalse
skipOnFirstNonTriggeredRulebooleanfalse
  • skipOnFirstAppliedRule: 当规则被触发并且成功执行行为后是否跳过下条规则。
  • skipOnFirstFailedRule : 当判断规则是否触发抛出异常或者触发成功但行为执行后抛出异常是否跳过下条规则。
  • skipOnFirstNonTriggeredRule : 当规则未被触发是否跳过下条规则。
  • rulePriorityThreshold : 如果规则优先级超过默认阈值,则跳过下条规则。

1、skipOnFirstAppliedRules示例

(1) FizzRule

import org.jeasy.rules.annotation.Action;
import org.jeasy.rules.annotation.Condition;
import org.jeasy.rules.annotation.Fact;
import org.jeasy.rules.annotation.Priority;
import org.jeasy.rules.annotation.Rule;

/**
 * 被5整除的规则
 * @author Nick Liu
 * @date 2023/8/4
 */
@Rule
public class FizzRule {

	@Condition
	public boolean isFizz(@Fact("number") Integer number) {
		return number % 5 == 0;
	}

	@Action
	public void printFizz(@Fact("number") Integer number) throws Exception {
		System.out.println("能被5整除的数为: " + number);
	}

	@Priority
	public int getPriority() {
		return 1;
	}

}

(2) BuzzRule

import org.jeasy.rules.annotation.Action;
import org.jeasy.rules.annotation.Condition;
import org.jeasy.rules.annotation.Fact;
import org.jeasy.rules.annotation.Priority;
import org.jeasy.rules.annotation.Rule;

/**
 * 被7整除的规则
 * @author Nick Liu
 * @date 2023/8/4
 */
@Rule
public class BuzzRule {

	@Condition
	public boolean isBuzz(@Fact("number") Integer number) {
		return number % 7 == 0;
	}

	@Action
	public void printBuzz(@Fact("number") Integer number) throws Exception {
		System.out.println("能被7整除的数为: " + number);
	}

	@Priority
	public int getPriority() {
		return 2;
	}
}

(3) FizzBuzzRule

import org.jeasy.rules.support.composite.UnitRuleGroup;

import java.util.Arrays;

/**
 * 既能被5整除也能被7整除的规则
 * @author Nick Liu
 * @date 2023/8/4
 */
public class FizzBuzzRule extends UnitRuleGroup {

	public FizzBuzzRule(Object... rules) {
		Arrays.stream(rules).forEach(super::addRule);
	}

	@Override
	public int getPriority() {
		return 0;
	}
}

(4) NonFizzBuzzRule

import org.jeasy.rules.annotation.Action;
import org.jeasy.rules.annotation.Condition;
import org.jeasy.rules.annotation.Fact;
import org.jeasy.rules.annotation.Priority;
import org.jeasy.rules.annotation.Rule;

/**
 * 既不能被5整除也不能被7整除的规则
 * @author Nick Liu
 * @date 2023/8/4
 */
@Rule
public class NonFizzBuzzRule {

	@Condition
	public boolean isNotFizzOrBuzz(@Fact("number") Integer number) {
		return number % 5 != 0 || number % 7 != 0;
	}

	@Action
	public void printInput(@Fact("number") Integer number) throws Exception {
		System.out.println("既不能被5整除也不能被7整除的数字: " + number);
	}

	@Priority
	public int getPriority() {
		return 3;
	}

}

(5) FizzBuzzRulesLauncher

import org.jeasy.rules.api.Facts;
import org.jeasy.rules.api.Rules;
import org.jeasy.rules.api.RulesEngine;
import org.jeasy.rules.api.RulesEngineParameters;
import org.jeasy.rules.core.DefaultRulesEngine;

/**
 * @author Nick Liu
 * @date 2023/8/4
 */
public class FizzBuzzRulesLauncher {

	public static void main(String[] args) {
		// 如果第一条规则满足条件且行为执行成功后则跳过执行后面的规则
		RulesEngineParameters parameters = new RulesEngineParameters().skipOnFirstAppliedRule(true);
		RulesEngine rulesEngine = new DefaultRulesEngine(parameters);

		// 规则注册
		Rules rules = new Rules();
		rules.register(new FizzRule());
		rules.register(new BuzzRule());
		rules.register(new FizzBuzzRule(new FizzRule(), new BuzzRule()));
		rules.register(new NonFizzBuzzRule());

		// 触发规则
		Facts facts = new Facts();
		for (int count = 0; count < 100; count++) {
			facts.put("number", count);
			rulesEngine.fire(rules, facts);
		}
	}
}

上面我们设置了默认规则引擎的skipOnFirstAppliedRule属性为true,优先级最高的规则是FizzBuzzRule,这是一个组合规则,也就是说当满足该组合规则的条件,且规则行为执行成功后,就会跳过后面低优先级的所有规则。

简单来说,上面规则的执行顺序是FizzBuzzRuleFizzRuleBuzzRuleNonFizzBuzzRule,语义就是先判断数字是否能被5和7同时整除,再判断是否能被5整除,再判断是否能被7整除,最后判断是否不能被5或7整除。

程序的运行结果如下:

能被5整除的数为: 0
能被7整除的数为: 0
既不能被5整除也不能被7整除的数字: 1
既不能被5整除也不能被7整除的数字: 2
既不能被5整除也不能被7整除的数字: 3
既不能被5整除也不能被7整除的数字: 4
能被5整除的数为: 5
既不能被5整除也不能被7整除的数字: 6
能被7整除的数为: 7
既不能被5整除也不能被7整除的数字: 8
既不能被5整除也不能被7整除的数字: 9
能被5整除的数为: 10
既不能被5整除也不能被7整除的数字: 11
既不能被5整除也不能被7整除的数字: 12
既不能被5整除也不能被7整除的数字: 13
能被7整除的数为: 14
能被5整除的数为: 15
既不能被5整除也不能被7整除的数字: 16
既不能被5整除也不能被7整除的数字: 17
既不能被5整除也不能被7整除的数字: 18
既不能被5整除也不能被7整除的数字: 19
能被5整除的数为: 20
能被7整除的数为: 21
既不能被5整除也不能被7整除的数字: 22
既不能被5整除也不能被7整除的数字: 23
既不能被5整除也不能被7整除的数字: 24
能被5整除的数为: 25
既不能被5整除也不能被7整除的数字: 26
既不能被5整除也不能被7整除的数字: 27
能被7整除的数为: 28
既不能被5整除也不能被7整除的数字: 29
能被5整除的数为: 30
既不能被5整除也不能被7整除的数字: 31
既不能被5整除也不能被7整除的数字: 32
既不能被5整除也不能被7整除的数字: 33
既不能被5整除也不能被7整除的数字: 34
能被5整除的数为: 35
能被7整除的数为: 35
既不能被5整除也不能被7整除的数字: 36
既不能被5整除也不能被7整除的数字: 37
既不能被5整除也不能被7整除的数字: 38
既不能被5整除也不能被7整除的数字: 39
能被5整除的数为: 40
既不能被5整除也不能被7整除的数字: 41
能被7整除的数为: 42
既不能被5整除也不能被7整除的数字: 43
既不能被5整除也不能被7整除的数字: 44
能被5整除的数为: 45
既不能被5整除也不能被7整除的数字: 46
既不能被5整除也不能被7整除的数字: 47
既不能被5整除也不能被7整除的数字: 48
能被7整除的数为: 49
能被5整除的数为: 50
既不能被5整除也不能被7整除的数字: 51
既不能被5整除也不能被7整除的数字: 52
既不能被5整除也不能被7整除的数字: 53
既不能被5整除也不能被7整除的数字: 54
能被5整除的数为: 55
能被7整除的数为: 56
既不能被5整除也不能被7整除的数字: 57
既不能被5整除也不能被7整除的数字: 58
既不能被5整除也不能被7整除的数字: 59
能被5整除的数为: 60
既不能被5整除也不能被7整除的数字: 61
既不能被5整除也不能被7整除的数字: 62
能被7整除的数为: 63
既不能被5整除也不能被7整除的数字: 64
能被5整除的数为: 65
既不能被5整除也不能被7整除的数字: 66
既不能被5整除也不能被7整除的数字: 67
既不能被5整除也不能被7整除的数字: 68
既不能被5整除也不能被7整除的数字: 69
能被5整除的数为: 70
能被7整除的数为: 70
既不能被5整除也不能被7整除的数字: 71
既不能被5整除也不能被7整除的数字: 72
既不能被5整除也不能被7整除的数字: 73
既不能被5整除也不能被7整除的数字: 74
能被5整除的数为: 75
既不能被5整除也不能被7整除的数字: 76
能被7整除的数为: 77
既不能被5整除也不能被7整除的数字: 78
既不能被5整除也不能被7整除的数字: 79
能被5整除的数为: 80
既不能被5整除也不能被7整除的数字: 81
既不能被5整除也不能被7整除的数字: 82
既不能被5整除也不能被7整除的数字: 83
能被7整除的数为: 84
能被5整除的数为: 85
既不能被5整除也不能被7整除的数字: 86
既不能被5整除也不能被7整除的数字: 87
既不能被5整除也不能被7整除的数字: 88
既不能被5整除也不能被7整除的数字: 89
能被5整除的数为: 90
能被7整除的数为: 91
既不能被5整除也不能被7整除的数字: 92
既不能被5整除也不能被7整除的数字: 93
既不能被5整除也不能被7整除的数字: 94
能被5整除的数为: 95
既不能被5整除也不能被7整除的数字: 96
既不能被5整除也不能被7整除的数字: 97
能被7整除的数为: 98
既不能被5整除也不能被7整除的数字: 99

2、skipOnFirstNonTriggeredRule示例

public class FizzBuzzRulesLauncher {

	public static void main(String[] args) {
		RulesEngineParameters parameters = new RulesEngineParameters().skipOnFirstNonTriggeredRule(true);
		RulesEngine rulesEngine = new DefaultRulesEngine(parameters);

		// 规则注册
		Rules rules = new Rules();
		rules.register(new FizzRule());
		rules.register(new BuzzRule());
		rules.register(new FizzBuzzRule(new FizzRule(), new BuzzRule()));
		rules.register(new NonFizzBuzzRule());

		// 触发规则
		Facts facts = new Facts();
		for (int count = 0; count < 100; count++) {
			facts.put("number", count);
			rulesEngine.fire(rules, facts);
		}
	}
}

这里我们把规则引擎参数调整为skipOnFirstNonTriggeredRule,意味着当优先级最高的规则没有被触发后就跳过下面的规则,执行结果如下:

能被5整除的数为: 0
能被7整除的数为: 0
能被5整除的数为: 0
能被7整除的数为: 0
能被5整除的数为: 35
能被7整除的数为: 35
能被5整除的数为: 35
能被7整除的数为: 35
能被5整除的数为: 70
能被7整除的数为: 70
能被5整除的数为: 70
能被7整除的数为: 70

3、skipOnFirstFailedRule示例

**
 *5整除的规则
 * @author Nick Liu
 * @date 2023/8/4
 */
@Rule
public class FizzRule {

	@Condition
	public boolean isFizz(@Fact("number") Integer number) {
		return number % 5 == 0;
	}

	@Action
	public void printFizz(@Fact("number") Integer number) throws Exception {
		System.out.println("能被5整除的数为: " + number);
		throw new RuntimeException("该数字能被5整除");
	}

	@Priority
	public int getPriority() {
		return 1;
	}

}

这里我们修改了FizzRule规则触发后的执行行为,当数字能被5整除时,执行行为后抛出异常。

public class FizzBuzzRulesLauncher {

	public static void main(String[] args) {
		RulesEngineParameters parameters = new RulesEngineParameters().skipOnFirstFailedRule(true);
		RulesEngine rulesEngine = new DefaultRulesEngine(parameters);

		// 规则注册
		Rules rules = new Rules();
		rules.register(new FizzRule());
		rules.register(new BuzzRule());
		rules.register(new FizzBuzzRule(new FizzRule(), new BuzzRule()));
		rules.register(new NonFizzBuzzRule());

		// 触发规则
		Facts facts = new Facts();
		for (int count = 0; count < 100; count++) {
			facts.put("number", count);
			rulesEngine.fire(rules, facts);
		}
	}
}

这里我们设置了规则引擎的参数skipOnFirstFailedRule,也就是当判断规则是否触发时发生异常或者执行行为时发生异常后,就跳过下一条规则,程序运行结果如下:

能被5整除的数为: 0
既不能被5整除也不能被7整除的数字: 1
既不能被5整除也不能被7整除的数字: 2
既不能被5整除也不能被7整除的数字: 3
既不能被5整除也不能被7整除的数字: 4
能被5整除的数为: 5
既不能被5整除也不能被7整除的数字: 6
能被7整除的数为: 7
既不能被5整除也不能被7整除的数字: 7
既不能被5整除也不能被7整除的数字: 8
既不能被5整除也不能被7整除的数字: 9
能被5整除的数为: 10
既不能被5整除也不能被7整除的数字: 11
既不能被5整除也不能被7整除的数字: 12
既不能被5整除也不能被7整除的数字: 13
能被7整除的数为: 14
既不能被5整除也不能被7整除的数字: 14
能被5整除的数为: 15
既不能被5整除也不能被7整除的数字: 16
既不能被5整除也不能被7整除的数字: 17
既不能被5整除也不能被7整除的数字: 18
既不能被5整除也不能被7整除的数字: 19
能被5整除的数为: 20
能被7整除的数为: 21
既不能被5整除也不能被7整除的数字: 21
既不能被5整除也不能被7整除的数字: 22
既不能被5整除也不能被7整除的数字: 23
既不能被5整除也不能被7整除的数字: 24
能被5整除的数为: 25
既不能被5整除也不能被7整除的数字: 26
既不能被5整除也不能被7整除的数字: 27
能被7整除的数为: 28
既不能被5整除也不能被7整除的数字: 28
既不能被5整除也不能被7整除的数字: 29
能被5整除的数为: 30
既不能被5整除也不能被7整除的数字: 31
既不能被5整除也不能被7整除的数字: 32
既不能被5整除也不能被7整除的数字: 33
既不能被5整除也不能被7整除的数字: 34
能被5整除的数为: 35
既不能被5整除也不能被7整除的数字: 36
既不能被5整除也不能被7整除的数字: 37
既不能被5整除也不能被7整除的数字: 38
既不能被5整除也不能被7整除的数字: 39
能被5整除的数为: 40
既不能被5整除也不能被7整除的数字: 41
能被7整除的数为: 42
既不能被5整除也不能被7整除的数字: 42
既不能被5整除也不能被7整除的数字: 43
既不能被5整除也不能被7整除的数字: 44
能被5整除的数为: 45
既不能被5整除也不能被7整除的数字: 46
既不能被5整除也不能被7整除的数字: 47
既不能被5整除也不能被7整除的数字: 48
能被7整除的数为: 49
既不能被5整除也不能被7整除的数字: 49
能被5整除的数为: 50
既不能被5整除也不能被7整除的数字: 51
既不能被5整除也不能被7整除的数字: 52
既不能被5整除也不能被7整除的数字: 53
既不能被5整除也不能被7整除的数字: 54
能被5整除的数为: 55
能被7整除的数为: 56
既不能被5整除也不能被7整除的数字: 56
既不能被5整除也不能被7整除的数字: 57
既不能被5整除也不能被7整除的数字: 58
既不能被5整除也不能被7整除的数字: 59
能被5整除的数为: 60
既不能被5整除也不能被7整除的数字: 61
既不能被5整除也不能被7整除的数字: 62
能被7整除的数为: 63
既不能被5整除也不能被7整除的数字: 63
既不能被5整除也不能被7整除的数字: 64
能被5整除的数为: 65
既不能被5整除也不能被7整除的数字: 66
既不能被5整除也不能被7整除的数字: 67
既不能被5整除也不能被7整除的数字: 68
既不能被5整除也不能被7整除的数字: 69
能被5整除的数为: 70
既不能被5整除也不能被7整除的数字: 71
既不能被5整除也不能被7整除的数字: 72
既不能被5整除也不能被7整除的数字: 73
既不能被5整除也不能被7整除的数字: 74
能被5整除的数为: 75
既不能被5整除也不能被7整除的数字: 76
能被7整除的数为: 77
既不能被5整除也不能被7整除的数字: 77
既不能被5整除也不能被7整除的数字: 78
既不能被5整除也不能被7整除的数字: 79
能被5整除的数为: 80
既不能被5整除也不能被7整除的数字: 81
既不能被5整除也不能被7整除的数字: 82
既不能被5整除也不能被7整除的数字: 83
能被7整除的数为: 84
既不能被5整除也不能被7整除的数字: 84
能被5整除的数为: 85
既不能被5整除也不能被7整除的数字: 86
既不能被5整除也不能被7整除的数字: 87
既不能被5整除也不能被7整除的数字: 88
既不能被5整除也不能被7整除的数字: 89
能被5整除的数为: 90
能被7整除的数为: 91
既不能被5整除也不能被7整除的数字: 91
既不能被5整除也不能被7整除的数字: 92
既不能被5整除也不能被7整除的数字: 93
既不能被5整除也不能被7整除的数字: 94
能被5整除的数为: 95
既不能被5整除也不能被7整除的数字: 96
既不能被5整除也不能被7整除的数字: 97
能被7整除的数为: 98
既不能被5整除也不能被7整除的数字: 98
既不能被5整除也不能被7整除的数字: 99

可以看到,既能被5整除也能被7整除的数,如3570只打印了一次。


三、组合规则

Easy Rules允许我们创建复杂的组合规则,所谓组合规则由多个单条规则组成,实际上就是组合设计模式的一种实现。

组合规则是一种抽象概念,因为组合规则可以通过不同的方式出发。Easy Rules提供了三种组合规则的实现,这些实现可以在easy-rules-support模块中可以找到,首先介绍一下3种组合规则:

  • UnitRuleGroup: 单元规则组,里面的所有规则都会被应用。
  • ActivationRuleGroup: 激活规则组,只会触发第一条适用的规则,该规则组中的所有规则默认根据优先级排序。
  • ConditionalRuleGroup: 条件式规则则,如果最高优先级的规则可以被触发,那么才会触发其它规则组中的规则。

1、UnitRuleGroup组合规则

该组合规则判断规则是否触发的代码如下,可以看到,所有的规则如果被触发,相应的行为就会被执行。

@Override
public boolean evaluate(Facts facts) {
    if (!rules.isEmpty()) {
        for (Rule rule : rules) {
            if (!rule.evaluate(facts)) {
                return false;
            }
        }
        return true;
    }
    return false;
}

@Override
public void execute(Facts facts) throws Exception {
    for (Rule rule : rules) {
        rule.execute(facts);
    }
}

2、ActivationRuleGroup组合规则

从该组合规则的源代码可以看到,该规则组中只有第一条可以被触发的规则才会执行相应的规则行为。

@Override
public boolean evaluate(Facts facts) {
   for (Rule rule : rules) {
       if (rule.evaluate(facts)) {
           selectedRule = rule;
           return true;
       }
   }
   return false;
}

@Override
public void execute(Facts facts) throws Exception {
   if (selectedRule != null) {
       selectedRule.execute(facts);
   }
}

3、ConditionalRuleGroup组合规则

该组合规则的源代码如下,可以看到只有最高优先级的规则可以被触发,才会继续应用其它规则中的规则。

 @Override
 public boolean evaluate(Facts facts) {
     successfulEvaluations = new HashSet<>();
     conditionalRule = getRuleWithHighestPriority();
     if (conditionalRule.evaluate(facts)) {
         for (Rule rule : rules) {
             if (rule != conditionalRule && rule.evaluate(facts)) {
                 successfulEvaluations.add(rule);
             }
         }
         return true;
     }
     return false;
 }

 /**
  * When a conditional rule group is executed, all rules that evaluated to true
  * are performed in their natural order, but with the conditional rule 
  * (the one with the highest priority) first.
  *
  * @param facts The facts.
  *
  * @throws Exception thrown if an exception occurs during actions performing
  */
 @Override
 public void execute(Facts facts) throws Exception {
     conditionalRule.execute(facts);
     for (Rule rule : sort(successfulEvaluations)) {
         rule.execute(facts);
     }
 }

 private Rule getRuleWithHighestPriority() {
     List<Rule> copy = sort(rules);
     // make sure we only have one rule with the highest priority
     Rule highest = copy.get(0);
     if (copy.size() > 1 && copy.get(1).getPriority() == highest.getPriority()) {
        throw new IllegalArgumentException("Only one rule can have highest priority");
     }
     return highest;
 }

 private List<Rule> sort(Set<Rule> rules) {
     return new ArrayList<>(new TreeSet<>(rules));
 }

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

java八股文面试[多线程]——synchronized 和lock的区别

其他差别&#xff1a; synchronized是隐式的加锁,lock是显式的加锁; synchronized底层采用的是objectMonitor,lock采用的AQS; synchronized在进行加锁解锁时,只有一个同步队列和一个等待队列, lock有一个同步队列,可以有多个等待队列; synchronized使用了object类的wait和noti…

经典问题解析四

关于动态内存分配 new 和 malloc 的区别是什么&#xff1f; delete 和 free 的区别是什么&#xff1f; new 关键字与 malloc 函数的区别 new 关键字是 C 的一部分 malloc 是由 C 库函数提供的函数 new 是以具体类型为单位进行内存分配 malloc 以字节为单位进行内存分配 …

利用R作圆环条形图

从理念上看&#xff0c;本质就是增加了圆环弧度的条形图。如上图2。 需要以下步骤&#xff1a; 数据处理&#xff0c;将EXCEL中的数据做成3*N的表格导入系统&#xff0c;代码如下&#xff1a;library(tidyverse) library(stringr)library(ggplot2)library(viridis) stuper &…

【前车之鉴】: 2023最新教程-将java程序打包到maven私服的正确打开方式,详细流程介绍不怕你掌握不了

文章目录 为什么看这篇整体流程1. 注册账号【首次需要】2. 工单申请【新项目必须】3. 项目配置【新项目必须】4. 授权认证【新项目必须】5. 一键发布 最后也很重要 为什么看这篇 一是当前网络上一些博客有遗漏部分&#xff0c;这里做补充&#xff0c;二是网上思路没错&#xff…

DC/DC开关电源学习笔记(一)开关电源技术概述

&#xff08;一&#xff09;开关电源技术概述 1.什么是开关电源&#xff1f;2.开关电源技术概述2.1 小型化、薄型化、轻量化、高频化2.2 高可靠性2.3 低噪声2.4 采用计算机辅助设计和控制 1.什么是开关电源&#xff1f; 开关模式电源&#xff08;Switch Mode Power Supply&…

JVM解密: 解构类加载与GC垃圾回收机制

文章目录 一. JVM内存划分二. 类加载机制1. 类加载过程2. 双亲委派模型 三. GC垃圾回收机制1. 找到需要回收的内存1.1 哪些内存需要回收&#xff1f;1.2 基于引用计数找垃圾(Java不采取该方案)1.3 基于可达性分析找垃圾(Java采取方案) 2. 垃圾回收算法2.1 标记-清除算法2.2 标记…

【QT】信号和槽(15)

前面的内容说了很多不同的控件如何使用&#xff0c;今天来看下QT的核心&#xff0c;信号与槽&#xff08;Signals and slots&#xff09;&#xff01; 简单理解一下&#xff0c;就是我们的信号与槽连接上了之后&#xff0c;发射一个信号给到槽&#xff0c;槽函数接收到了这个信…

0103水平分片-jdbc-shardingsphere-中间件

文章目录 1 准备服务器1.1 创建server-order0容器1.2 创建server-order1容器 2、基本水平分片2.1、基本配置2.2、数据源配置2.3、标椎分片表配置2.4、行表达式2.5、分片算法配置2.6、分布式序列算法 3、多表关联3.1、创建关联表3.2、创建实体类3.3、创建Mapper3.4、配置关联表3…

Linux 桌面上的 Firefox 面临着大问题

导读毫无疑问&#xff0c;无论是在桌面、笔记本电脑还是移动设备上&#xff0c;浏览器都是任何操作系统中最重要的应用之一。 如果没有一个功能强大、快速且稳定的浏览器&#xff0c;操作系统的实用性将大幅度降低&#xff0c;以至于我相当确定&#xff0c;如果一个操作系统没有…

哈佛商学院教授:每个老板使用ChatGPT之类AI工具的理由

哈佛商学院教授Karim Lakhani表示&#xff0c;每个老板都应该使用生成式人工智能工具&#xff0c;生成式AI为老板提供了一种更高效的工作方式&#xff0c;在提高生产力、提高规模、与客户沟通以及促进销售、社交媒体内容更新和新产品开发等方面都有积极意义。 Karim Lakhani表…

Vulnhub系列靶机---JIS-CTF-VulnUpload-CTF01靶机

文章目录 1、网卡配置2、信息收集主机发现端口扫描目录扫描 3、漏洞探测4、漏洞利用一句话木马蚁剑 GetShellSSH连接提权 JIS文档说明 JIS-CTF-VulnUpload-CTF01靶机下载地址 该靶机有5个flag 1、网卡配置 开启靶机&#xff0c;看见加载的进度条按shift&#xff0c;看到如下界…

大数据扫盲(2): 数据分析BI与ETL的紧密关系——ETL是成功BI的先决条件

着业务的发展每个企业都将产生越来越多的数据&#xff0c;然后这些数据本身并不能直接带来洞察力并产生业务价值。为了释放数据的潜力&#xff0c;数据分析BI&#xff08;商业智能&#xff09;成为了现代企业不可或缺的一部分。然而&#xff0c;在数据分析的背后&#xff0c;有…

SQLmap使用

文章目录 利用sqlmap 注入得到cms网站后台管理员账密获取数据库名称获取cms数据库的表名获取users表中的字段&#xff08;内容&#xff09;获取username字段和password字段的内容 salmap破解psot请求数据包salmap获取getshell 利用sqlmap 注入得到cms网站后台管理员账密 获取数…

关闭jenkins插件提醒信息

jenkins提醒信息和安全警告可以帮助我们了解插件或者jenkins的更新情况&#xff0c;但是有些插件是已经不维护了&#xff0c;提醒却一直存在&#xff0c;看着糟心&#xff0c;就像下面的提示 1、关闭插件提醒 找到如下位置&#xff1a;系统管理-系统配置-管理监控配置 打开管…

Error running ‘Tomcat 8.5.29‘ Address localhost:1099 is already in use

一、Error running ‘Tomcat 8.5.29’ Address localhost:1099 is already in use 原因&#xff1a;端口1099被占用了。 二、解决 2.1 解决方法一-结束该端口1099占用 //1-查看端口占用&#xff0c;根据端口号1099&#xff0c;获取PID(进程ID) netstat -ano | findstr "…

Plugin “Chinese (Simplified) Language Pack / 中文语言包“ was not installed

idea2020.3.4版本无法直接在下载汉化包 1、通常情况下&#xff0c;直接在idea里面下载插件即可&#xff0c;这里下载失败后进行下一步操作&#xff1a; 2、https://plugins.jetbrains.com/plugin/13710-chinese-simplified-language-pack----/versions 第一步&#xff1a;找到…

在iPhone 15发布之前,iPhone在智能手机出货量上占据主导地位,这对安卓来说是个坏消息

可以说这是一记重拳&#xff0c;但似乎没有一个有价值的竞争者能与苹果今年迄今为止的智能手机出货量相媲美。 事实上&#xff0c;根据Omdia智能手机型号市场跟踪机构收集的数据&#xff0c;苹果的iPhone占据了前四名。位居榜首的是iPhone 14 Pro Max&#xff0c;2023年上半年…

4G智慧电力物联网:建设高效智能,引领电力行业革新!

随着4G与物联网技术的快速发展为电力行业提供了更高效、可靠、智能化的解决方案。本文中智联物联将为大家分享智慧电力系统中的一些关键的物联网技术和通讯设备&#xff0c;如工业4G路由器、分布式发电站、数据采集传输、远程监控管理以及变电站监测。 光伏发电站是电力行业中重…

<AMBA总线篇> AXI总线协议介绍

目录 01 AXI协议简介 AXI协议特性 AXI协议传输特性 02 AXI协议架构 AXI协议架构 write transaction(写传输) read tramsaction(读传输) Interface and interconnect 典型的AXI系统拓扑 03 文章总结 大家好&#xff0c;这里是程序员杰克。一名平平无奇的嵌入式软件工程…

大数据之linux入门

一、linux是什么 linux操作系统 开发者是林纳斯-托瓦兹&#xff0c;出于个人爱好编写。linux是一个基于posix和unix的多用户、多任务、支持多线程和多CPU的操作系统。 Unix是20世纪70年代初出现的一个操作系统&#xff0c;除了作为网络操作系统之外&#xff0c;还可以作为单…