Spring Boot集成Spring Batch快速入门Demo

news2024/11/27 21:00:11

1.什么是Spring Batch?

Spring Batch 是一个轻量级的开源框架,它提供了一种简单的方式来处理大量的数据。它基于Spring框架,提供了一套批处理框架,可以处理各种类型的批处理任务,如ETL、数据导入/导出、报表生成等。Spring Batch提供了一些重要的概念,如Job、Step、ItemReader、ItemProcessor、ItemWriter等,这些概念可以帮助我们构建可重用的批处理应用程序。通过Spring Batch,我们可以轻松地实现批处理的并发、容错、重试等功能,同时也可以方便地与其他Spring组件集成,如Spring Boot、Spring Data等。总之,Spring Batch是一个非常强大、灵活、易于使用的批处理框架,可以帮助我们快速构建高效、可靠的批处理应用程序。

分层架构

spring-batch-layers

可以看到它分为三层,分别是:

  • Application应用层:包含了所有任务batch jobs和开发人员自定义的代码,主要是根据项目需要开发的业务流程等。
  • Batch Core核心层:包含启动和管理任务的运行环境类,如JobLauncher等。
  • Batch Infrastructure基础层:上面两层是建立在基础层之上的,包含基础的读入reader写出writer、重试框架等。

主要概念

spring-batch-reference-model

2.2.1 JobRepository

专门负责与数据库打交道,对整个批处理的新增、更新、执行进行记录。所以Spring Batch是需要依赖数据库来管理的。

2.2.2 任务启动器JobLauncher

负责启动任务Job

2.2.3 任务Job

Job是封装整个批处理过程的单位,跑一个批处理任务,就是跑一个Job所定义的内容。

111

  上图介绍了Job的一些相关概念:

  • Job:封装处理实体,定义过程逻辑。
  • JobInstanceJob的运行实例,不同的实例,参数不同,所以定义好一个Job后可以通过不同参数运行多次。
  • JobParameters:与JobInstance相关联的参数。
  • JobExecution:代表Job的一次实际执行,可能成功、可能失败。

所以,开发人员要做的事情,就是定义Job

2.2.4 步骤Step

Step是对Job某个过程的封装,一个Job可以包含一个或多个Step,一步步的Step按特定逻辑执行,才代表Job执行完成。

222

  通过定义Step来组装Job可以更灵活地实现复杂的业务逻辑。

2.2.5 输入——处理——输出

所以,定义一个Job关键是定义好一个或多个Step,然后把它们组装好即可。而定义Step有多种方法,但有一种常用的模型就是输入——处理——输出,即Item ReaderItem ProcessorItem Writer。比如通过Item Reader从文件输入数据,然后通过Item Processor进行业务处理和数据转换,最后通过Item Writer写到数据库中去。 Spring Batch为我们提供了许多开箱即用的ReaderWriter,非常方便。

 

2.环境搭建

参照代码仓库mysql模块里面docker目录搭建

3.代码工程

实验目标

如何使用 Spring Boot 创建各种不同类型 Spring Batch Job

pom.xml

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>springboot-demo</artifactId>
        <groupId>com.et</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>SpringBatch</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-batch</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

job

第一个简单的任务

package com.et.batch.job;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

@Component
public class FirstJobDemo {

    @Autowired
    private JobBuilderFactory jobBuilderFactory;
    @Autowired
    private StepBuilderFactory stepBuilderFactory;

    @Bean
    public Job firstJob() {
        return jobBuilderFactory.get("firstJob")
                .start(step())
                .build();
    }

    private Step step() {
        return stepBuilderFactory.get("step")
                .tasklet((contribution, chunkContext) -> {
                    System.out.println("execute  step....");
                    return RepeatStatus.FINISHED;
                }).build();
    }
}

多步骤的job

package com.et.batch.job;

import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

@Component
public class MultiStepJobDemo {

    @Autowired
    private JobBuilderFactory jobBuilderFactory;
    @Autowired
    private StepBuilderFactory stepBuilderFactory;

    @Bean
    public Job multiStepJob() {
        /*return jobBuilderFactory.get("multiStepJob")
                .start(step1())
                .next(step2())
                .next(step3())
                .build();*/
        // control the next step by last Status
        return jobBuilderFactory.get("multiStepJob2")
          .start(step1())
                .on(ExitStatus.COMPLETED.getExitCode()).to(step2())
                .from(step2())
                .on(ExitStatus.COMPLETED.getExitCode()).to(step3())
                .from(step3()).end()
                .build();
    }

    private Step step1() {
        return stepBuilderFactory.get("step1")
                .tasklet((stepContribution, chunkContext) -> {
                    System.out.println("execute step1。。。");
                    return RepeatStatus.FINISHED;
                }).build();
    }

    private Step step2() {
        return stepBuilderFactory.get("step2")
                .tasklet((stepContribution, chunkContext) -> {
                    System.out.println("execute step2。。。");
                    return RepeatStatus.FINISHED;
                }).build();
    }

    private Step step3() {
        return stepBuilderFactory.get("step3")
                .tasklet((stepContribution, chunkContext) -> {
                    System.out.println("execute step3。。。");
                    return RepeatStatus.FINISHED;
                }).build();
    }
}

多flow控制的job, 创建一个flow对象,包含若干个step

package com.et.batch.job;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.job.builder.FlowBuilder;
import org.springframework.batch.core.job.flow.Flow;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

@Component
public class FlowJobDemo {

    @Autowired
    private JobBuilderFactory jobBuilderFactory;
    @Autowired
    private StepBuilderFactory stepBuilderFactory;

    @Bean
    public Job flowJob() {
        return jobBuilderFactory.get("flowJob")
                .start(flow())
                .next(step3())
                .end()
                .build();
    }

    private Step step1() {
        return stepBuilderFactory.get("step1")
                .tasklet((stepContribution, chunkContext) -> {
                    System.out.println("execute step1。。。");
                    return RepeatStatus.FINISHED;
                }).build();
    }

    private Step step2() {
        return stepBuilderFactory.get("step2")
                .tasklet((stepContribution, chunkContext) -> {
                    System.out.println("execute step2。。。");
                    return RepeatStatus.FINISHED;
                }).build();
    }

    private Step step3() {
        return stepBuilderFactory.get("step3")
                .tasklet((stepContribution, chunkContext) -> {
                    System.out.println("execute step3。。。");
                    return RepeatStatus.FINISHED;
                }).build();
    }

    private Flow flow() {
        return new FlowBuilder<Flow>("flow")
                .start(step1())
                .next(step2())
                .build();
    }
}

并发执行的jobs

package com.et.batch.job;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.job.builder.FlowBuilder;
import org.springframework.batch.core.job.flow.Flow;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.core.task.SimpleAsyncTaskExecutor;
import org.springframework.stereotype.Component;

@Component
public class SplitJobDemo {

    @Autowired
    private JobBuilderFactory jobBuilderFactory;
    @Autowired
    private StepBuilderFactory stepBuilderFactory;

    @Bean
    public Job splitJob() {
        return jobBuilderFactory.get("splitJob")
                .start(flow1())
                .split(new SimpleAsyncTaskExecutor()).add(flow2())
                .end()
                .build();

    }

    private Step step1() {
        return stepBuilderFactory.get("step1")
                .tasklet((stepContribution, chunkContext) -> {
                    System.out.println("execute step1。。。");
                    return RepeatStatus.FINISHED;
                }).build();
    }

    private Step step2() {
        return stepBuilderFactory.get("step2")
                .tasklet((stepContribution, chunkContext) -> {
                    System.out.println("execute step2。。。");
                    return RepeatStatus.FINISHED;
                }).build();
    }

    private Step step3() {
        return stepBuilderFactory.get("step3")
                .tasklet((stepContribution, chunkContext) -> {
                    System.out.println("execute step3。。。");
                    return RepeatStatus.FINISHED;
                }).build();
    }

    private Flow flow1() {
        return new FlowBuilder<Flow>("flow1")
                .start(step1())
                .next(step2())
                .build();
    }

    private Flow flow2() {
        return new FlowBuilder<Flow>("flow2")
                .start(step3())
                .build();
    }
}

根据上次运行结果判断是否执行下一步

package com.et.batch.job;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

@Component
public class DeciderJobDemo {

    @Autowired
    private JobBuilderFactory jobBuilderFactory;
    @Autowired
    private StepBuilderFactory stepBuilderFactory;
    @Autowired
    private MyDecider myDecider;

    @Bean
    public Job deciderJob() {
        return jobBuilderFactory.get("deciderJob")
                .start(step1())
                .next(myDecider)
                .from(myDecider).on("weekend").to(step2())
                .from(myDecider).on("workingDay").to(step3())
                .from(step3()).on("*").to(step4())
                .end()
                .build();
    }

    private Step step1() {
        return stepBuilderFactory.get("step1")
                .tasklet((stepContribution, chunkContext) -> {
                    System.out.println("execute step1。。。");
                    return RepeatStatus.FINISHED;
                }).build();
    }

    private Step step2() {
        return stepBuilderFactory.get("step2")
                .tasklet((stepContribution, chunkContext) -> {
                    System.out.println("execute step2。。。");
                    return RepeatStatus.FINISHED;
                }).build();
    }

    private Step step3() {
        return stepBuilderFactory.get("step3")
                .tasklet((stepContribution, chunkContext) -> {
                    System.out.println("execute step3。。。");
                    return RepeatStatus.FINISHED;
                }).build();
    }


    private Step step4() {
        return stepBuilderFactory.get("step4")
                .tasklet((stepContribution, chunkContext) -> {
                    System.out.println("execute step4。。。");
                    return RepeatStatus.FINISHED;
                }).build();
    }
}

父子嵌套job

package com.et.batch.job;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.step.builder.JobStepBuilder;
import org.springframework.batch.core.step.builder.StepBuilder;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.transaction.PlatformTransactionManager;

@Component
public class NestedJobDemo {

    @Autowired
    private JobBuilderFactory jobBuilderFactory;
    @Autowired
    private StepBuilderFactory stepBuilderFactory;
    @Autowired
    private JobLauncher jobLauncher;
    @Autowired
    private JobRepository jobRepository;
    @Autowired
    private PlatformTransactionManager platformTransactionManager;

    @Bean
    public Job parentJob() {
        return jobBuilderFactory.get("parentJob")
                .start(childJobOneStep())
                .next(childJobTwoStep())
                .build();
    }


    private Step childJobOneStep() {
        return new JobStepBuilder(new StepBuilder("childJobOneStep"))
                .job(childJobOne())
                .launcher(jobLauncher)
                .repository(jobRepository)
                .transactionManager(platformTransactionManager)
                .build();
    }

    private Step childJobTwoStep() {
        return new JobStepBuilder(new StepBuilder("childJobTwoStep"))
                .job(childJobTwo())
                .launcher(jobLauncher)
                .repository(jobRepository)
                .transactionManager(platformTransactionManager)
                .build();
    }

    private Job childJobOne() {
        return jobBuilderFactory.get("childJobOne")
                .start(
                    stepBuilderFactory.get("childJobOneStep")
                            .tasklet((stepContribution, chunkContext) -> {
                                System.out.println("subtask1。。。");
                                return RepeatStatus.FINISHED;
                            }).build()
                ).build();
    }

    private Job childJobTwo() {
        return jobBuilderFactory.get("childJobTwo")
                .start(
                    stepBuilderFactory.get("childJobTwoStep")
                            .tasklet((stepContribution, chunkContext) -> {
                                System.out.println("subtask2。。。");
                                return RepeatStatus.FINISHED;
                            }).build()
                ).build();
    }
}

application.yaml

自动会初始化脚本,只需要建立以恶搞空库就行

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/springbatch
    username: root
    password: 123456

  batch:
    jdbc:
      schema: classpath:org/springframework/batch/core/schema-mysql.sql
    initialize-schema: always #Since Spring Boot 2.5.0 use spring.batch.jdbc.initialize-schema=never

    job:
      enabled: true

以上只是一些关键代码,所有代码请参见下面代码仓库

代码仓库

  • GitHub - Harries/springboot-demo: a simple springboot demo with some components for example: redis,solr,rockmq and so on.

4.测试

  • 启动Spring Boot应用程序,系统会自动运行job,跑过一次,下次启动不会继续执行
  • 如果要执行定时任务,可以利用spring提供的scheduledTaskRegistrar注册一个定时任务,扫描最新的定时任务,将这些定时任务注册到scheduleFuture中从而实现动态定时任务。

5.引用

  • Batch Applications :: Spring Boot
  • Spring Boot集成Spring Batch快速入门Demo | Harries Blog™

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

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

相关文章

Windows 、Linux、MacOS 进程管理机制

本心、输入输出、结果 文章目录 Windows 、Linux、MacOS 进程管理机制前言Windows 进程管理机制Linux 进程管理macOS 进程管理内存不够了,几个操作系统如何处理Windows 、Linux、MacOS 进程管理机制 编辑 | 简简单单 Online zuozuo 地址 | https://blog.csdn.net/qq_15071263 …

Webstorm-恢复默认UI布局

背景 在使用Webstorm的时候,有时候进行个性化设置,如字体、界面布局等. 但是设置后的效果不理想,想要重新设置回原来的模样,却找不到设置项. 这里提供一种解决方案,恢复默认设置,即恢复到最初刚下载好后的设置. 操作步骤 步骤一:打开setting 步骤二:搜索Restore Default,找到…

AI智能名片微信小程序在IP合作中的创新应用与品牌赋能策略

摘要&#xff1a;在数字化时代&#xff0c;品牌与IP&#xff08;Intellectual Property&#xff09;的合作已成为推动品牌增长、深化市场影响力的关键策略。AI智能名片微信小程序&#xff0c;作为新兴的数字营销工具&#xff0c;凭借其智能化、便捷化、社交化的特性&#xff0c…

Kafka架构详解之分区Partition

目录 一、简介二、架构三、分区Partition1.分区概念2.Offsets&#xff08;偏移量&#xff09;和消息的顺序3.分区如何为Kafka提供扩展能力4.producer写入策略5.consumer消费机制 一、简介 Apache Kafka 是分布式发布 - 订阅消息系统&#xff0c;在 kafka 官网上对 kafka 的定义…

shell详细介绍(清晰明了)

一、shell的介绍 Shell ⼀个命令解释器&#xff0c;它接收应⽤程序/⽤户命令&#xff0c;然后调⽤操作系统内核。 Shell还是⼀个功能强⼤的编程语⾔&#xff0c;易编写、易调试、灵活性强。 (1) Linux提供的shell解释器有 (2) bash 和 sh的关系 (3) Centos默认的Shell解析器…

前端学习(三)之CSS

一、什么是CSS html定义网页的结构和信息&#xff08;骨架血肉&#xff09;css定义网页的样式&#xff08;衣服&#xff09;js定义用户和网页的交互逻辑&#xff08;动作&#xff09; 通过CSS&#xff0c;可以指定页面中各个元素的颜色、字体、大小、间距、边框、背景等样式&…

YOLOv8改进 | Neck | 注意力尺度序列融合的检测框架ASF-YOLO

秋招面试专栏推荐 &#xff1a;深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 &#x1f4a1;&#x1f4a1;&#x1f4a1;本专栏所有程序均经过测试&#xff0c;可成功执行&#x1f4a1;&#x1f4a1;&#x1f4a1; 专栏目录 &#xff1a;《YOLOv8改进有效…

spring boot(学习笔记第十四课)

spring boot(学习笔记第十四课) Spring Security的密码加密&#xff0c;基于数据库认证 学习内容&#xff1a; Spring Security的密码加密基于数据库认证 1. Spring Security的密码加密 如果用户的密码保存在数据库中是以明文保存&#xff0c;对于公司的安全将是灾难性的&…

SpringBoot中fastjson扩展: 自定义序列化和反序列化方法实战

❃博主首页 &#xff1a; 「码到三十五」 &#xff0c;同名公众号 :「码到三十五」&#xff0c;wx号 : 「liwu0213」 ☠博主专栏 &#xff1a; <mysql高手> <elasticsearch高手> <源码解读> <java核心> <面试攻关> ♝博主的话 &#xff1a…

安全防御---防火墙综合实验3

安全防御—防火墙综合实验3 一、实验拓扑图 二、实验要求 12&#xff0c;对现有网络进行改造升级&#xff0c;将当个防火墙组网改成双机热备的组网形式&#xff0c;做负载分担模式&#xff0c;游客区和DMZ区走FW3&#xff0c;生产区和办公区的流量走FW1 13&#xff0c;办公区…

【软件配置】不使用ROS系统,不进行编译,纯python环境配置rosbag,从而解析.bag文件

【软件配置】不使用ROS系统&#xff0c;不进行编译&#xff0c;纯python环境配置rosbag&#xff0c;从而解析.bag文件 【anaconda】conda创建、查看、删除虚拟环境&#xff08;anaconda命令集&#xff09;_conda 创建环境-CSDN博客 【Windows配置三】Python3.6安装rosbag_ros…

4.基础知识-数据库技术基础

基础知识 一、数据库基本概念1、数据库系统基础知识2、三级模式-两级映像3、数据库设计4、数据模型&#xff1a;4.1 E-R模型★4.2 关系模型★ 5、关系代数 二、规范化和并发控制1、函数依赖2、键与约束3、范式★3.1 第一范式1NF实例3.2 第二范式2NF3.3 第三范式3NF3.4 BC范式BC…

鸿蒙智联:一统多设备,跨端融合新魔法

在当今科技飞速发展的时代&#xff0c;操作系统的优劣直接影响着用户的体验和设备的性能。而鸿蒙系统&#xff0c;宛如一颗璀璨的新星&#xff0c;凭借其卓越的跨端能力&#xff0c;为我们展现了一个全新的科技世界。 鸿蒙系统的最大魅力之一&#xff0c;就在于它能够实现一个系…

【嵌入式开发之数据结构】树的基本概念、逻辑结构和四种常用的遍历算法及实现

树&#xff08;Tree&#xff09;的定义及基本概念 树的定义 树(Tree)是个结点的有限集合T&#xff0c;它满足两个条件&#xff1a; 有且仅有一个特定的称为根&#xff08;Root&#xff09;的节点&#xff1b;其余的节点分为个互不相交的有限合集&#xff0c;其中每一个集合又…

【无重叠空间】python刷题记录

润到贪心篇。 class Solution:def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:#十行贪心大神if not intervals:return 0#按照第第二个元素进行排序&#xff0c;贪心思想&#xff0c;参考活动安排都是以结束时间进行排序的intervals.sort(keylambda x:…

分离式网络变压器的集成化设计替代传统网络变压器(网络隔离滤波器)尝试

Hqst盈盛&#xff08;华强盛&#xff09;电子导读&#xff1a;今天分享的是应用了分离式网络变压器设计的的新型网络变压器&#xff08;网络隔离变压器&#xff09; 今天我们一起来看这款新型网络变压器&#xff0c;它就是应用分离式网络变压器集成到电路板上&#xff0c;加上外…

git协同开发与冲突解决

协同开发流程 基本的使用方法 # 1 多人开发同一个项目-张三&#xff1a;本地 版本库-李四&#xff1a;本地 版本库-我&#xff1a; 本地 版本库----远程仓库&#xff1a;本地版本库内容--》推送到远程仓库-----# 2 演示&#xff08;我是项目管理员&#xff09;-1 增加几个开发…

(二刷)代码随想录第21天|236. 二叉树的最近公共祖先

236. 二叉树的最近公共祖先 递归三部曲&#xff1a; 1、确定参数和返回值&#xff1a; class Solution {public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {} 2、确定中止条件&#xff1a; if (root null || root p || root q) { // 递归结…

lua 游戏架构 之 SceneLoad场景加载之 SceneBase (三)

谢谢大家关注一下啊我的微信 框架上 设计一个 基类 SceneLoad&#xff1a;BaseSceneLoad lua 游戏架构 之 SceneLoad场景加载&#xff08;一&#xff09;-CSDN博客https://blog.csdn.net/heyuchang666/article/details/140560014?spm1001.2014.3001.5501 设计多个 场景类&a…

无需业务改造,一套数据库满足 OLTP 和 OLAP,GaiaDB 发布并行查询能力

在企业中通常存在两类数据处理场景&#xff0c;一类是在线事务处理场景&#xff08;OLTP&#xff09;&#xff0c;例如交易系统&#xff0c;另一类是在线分析处理场景&#xff08;OLAP&#xff09;&#xff0c;例如业务报表。 OLTP 数据库擅长处理数据的增、删、改&#xff0c…