当前位置: 首页 > news >正文

springboot整合springbatch批处理

springboot整合springbatch实现批处理

  • 简介
  • 项目搭建
    • 步骤

简介

项目搭建

参考博客【场景实战】Spring Boot + Spring Batch 实现批处理任务,保姆级教程

步骤

1.建表
建表sql

CREATE TABLE `student` (`id` int NOT NULL AUTO_INCREMENT,`name` varchar(100) NOT NULL COMMENT '姓名',`class_name` varchar(20) DEFAULT NULL COMMENT '班级名称',`china_score` varchar(4) DEFAULT NULL COMMENT '语文成绩',`math_score` varchar(4) DEFAULT NULL COMMENT '数学成绩',`english_score` varchar(4) DEFAULT NULL COMMENT '英语成绩',`sex` tinyint(1) NOT NULL COMMENT '性别:0-男,1-女',`birthday` date NOT NULL COMMENT '生日',`card_id` varchar(20) NOT NULL COMMENT '身份证号',`phone` varchar(20) NOT NULL COMMENT '手机号',PRIMARY KEY (`id`),UNIQUE KEY `card_id` (`card_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='学生表'

2.pom文件

<?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"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>springbatch_study</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><parent><artifactId>spring-boot-starter-parent</artifactId><groupId>org.springframework.boot</groupId><version>2.3.5.RELEASE</version></parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.3.5.RELEASE</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.3</version></dependency><!--swagger页面--><dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-spring-boot-starter</artifactId><version>2.0.0</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-batch</artifactId><version>2.3.5.RELEASE</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><version>2.3.5.RELEASE</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.24</version></dependency><dependency><groupId>org.hibernate.validator</groupId><artifactId>hibernate-validator</artifactId><version>6.2.2.Final</version></dependency></dependencies></project>

3.启动类

@SpringBootApplication
@EnableSwagger2
public class BatchService {public static void main(String[] args) {SpringApplication.run(BatchService.class,args);}}

4.配置文件

server:port: 8081
spring:application:name: spring-batch-studydatasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/test?serverTimeZone=Asia/Shanghai&characterEncoding=utf-8username: rootpassword: rootbatch:job:enabled: false #需要jobLaucher.run执行initialize-schema: never #第一次没有新建batch内置表时为always,创建内置表后设置为never

注意:spring.batch.initialize-schema第一次运行时写为always,运行后会自动生产batch内置表
5.实体类

package com.test.batch.entity;import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;import java.util.Date;/*** @author 1*/
@Data
public class Student {@TableId(type = IdType.AUTO)private Integer id;/*** '姓名'*/private String name;/*** '班级名称'*/private String className;/*** '语文成绩'*/private String chinaScore;/*** '数学成绩'*/private String mathScore;/*** 英语成绩*/private String englishScore;/*** '性别:0-男,1-女'*/private Integer sex;/*** '生日'*/@JsonFormat(pattern = "yyyy-MM-dd")private Date birthday;/*** '身份证号'*/private String cardId;/*** '手机号'*/private String phone;}

6.batch核心配置类

package com.test.batch.config;import com.test.batch.entity.Student;
import com.test.batch.listen.MyBeanValidator;
import com.test.batch.listen.MyJobListener;
import com.test.batch.listen.MyReaderListener;
import com.test.batch.listen.MyWriteListener;
import com.test.batch.processor.MyProcessor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.core.launch.support.SimpleJobLauncher;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.support.JobRepositoryFactoryBean;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.database.BeanPropertyItemSqlParameterSourceProvider;
import org.springframework.batch.item.database.JdbcBatchItemWriter;
import org.springframework.batch.item.file.FlatFileItemReader;
import org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper;
import org.springframework.batch.item.file.mapping.DefaultLineMapper;
import org.springframework.batch.item.file.transform.DelimitedLineTokenizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.core.io.ClassPathResource;
import org.springframework.transaction.PlatformTransactionManager;import javax.sql.DataSource;
import java.text.SimpleDateFormat;
import java.util.Date;/*** @author 1*/
@Configuration
@EnableBatchProcessing
@Slf4j
public class BatchConfig {/*** JobRepository定义及数据库的操作* @param dataSource* @param transactionManager* @return* @throws Exception*/@Beanpublic JobRepository myJobRepository(DataSource dataSource, PlatformTransactionManager transactionManager)throws Exception{JobRepositoryFactoryBean jobRepositoryFactoryBean = new JobRepositoryFactoryBean();jobRepositoryFactoryBean.setDatabaseType("mysql");jobRepositoryFactoryBean.setTransactionManager(transactionManager);jobRepositoryFactoryBean.setDataSource(dataSource);return jobRepositoryFactoryBean.getObject();}/*** JobLauncher:job的启动器,绑定相关的Repository* @param dataSource* @param transactionManager* @return* @throws Exception*/@Beanpublic SimpleJobLauncher myJobLauncher(DataSource dataSource,PlatformTransactionManager transactionManager)throws Exception{SimpleJobLauncher jobLauncher = new SimpleJobLauncher();jobLauncher.setJobRepository(myJobRepository(dataSource,transactionManager));return jobLauncher;}/*** 定义job* @param jobBuilderFactory* @param myStep* @return*/@Beanpublic Job myJob(JobBuilderFactory jobBuilderFactory, Step myStep){return jobBuilderFactory.get("myJob").incrementer(new RunIdIncrementer()).flow(myStep).end().listener(myJobListener()).build();}/*** 注册job监听器* @return*/@Beanpublic MyJobListener myJobListener(){return new MyJobListener();}/*** 定义itemReader,读取文件数据+entity实体映射* @return*/@Beanpublic ItemReader<Student> reader(){FlatFileItemReader<Student> reader = new FlatFileItemReader<>();//设置文件路径reader.setResource(new ClassPathResource("static/student.csv"));reader.setLineMapper(new DefaultLineMapper<Student>(){{setLineTokenizer(new DelimitedLineTokenizer(){{setNames(new String[]{"name","className","chinaScore","mathScore","englishScore","sex","birthday","cardIdd","phone"});}});setFieldSetMapper(new BeanWrapperFieldSetMapper<Student>(){{setTargetType(Student.class);//设置日期转换setConversionService(createConversionService());}});}});return reader;}public ConversionService createConversionService() {DefaultConversionService conversionService = new DefaultConversionService();DefaultConversionService.addDefaultConverters(conversionService);conversionService.addConverter(new Converter<String, Date>() {@Overridepublic Date convert(String text) {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-mm-dd");Date date = new Date();try {date = sdf.parse(text);}catch (Exception e){log.error("日期转换异常 :{}",e);}return date;}});return conversionService;}/*** 注册ItemProcessor,处理数据* @return*/@Beanpublic ItemProcessor<Student,Student> processor(){MyProcessor myProcessor = new MyProcessor();myProcessor.setValidator(myBeanValidator());return myProcessor;}@Beanpublic MyBeanValidator myBeanValidator(){return new MyBeanValidator<Student>();}/*** 定义ItemWriter,指定DataSource,设置批量插入sql语句,写入数据库* @param dataSource* @return*/@Beanpublic ItemWriter<Student> writer(DataSource dataSource){JdbcBatchItemWriter<Student> writer = new JdbcBatchItemWriter<>();writer.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>());String sql = "insert into student (name,class_name,china_score,math_score,english_score,sex,birthday,card_id,phone) " +"values (:name,:className,:chinaScore,:mathScore,:englishScore,:sex,:birthday,:cardId,:phone)";writer.setSql(sql);writer.setDataSource(dataSource);return writer;}@Beanpublic Step myStep(StepBuilderFactory factory,ItemReader<Student> reader,ItemWriter<Student> writer,ItemProcessor<Student,Student> processor){return factory.get("myStep").<Student,Student>chunk(5000).reader(reader).faultTolerant().retryLimit(3).retry(Exception.class).skip(Exception.class).skipLimit(2).listener(new MyReaderListener()).processor(processor).writer(writer).faultTolerant().skip(Exception.class).skipLimit(2).listener(new MyWriteListener()).build();}
}

7.自定义处理器

package com.test.batch.processor;import com.test.batch.entity.Student;
import lombok.extern.slf4j.Slf4j;
import org.springframework.batch.item.validator.ValidatingItemProcessor;
import org.springframework.batch.item.validator.ValidationException;/*** @author 1*/
@Slf4j
public class MyProcessor extends ValidatingItemProcessor<Student> {private Integer GOOD = 90;private Integer  BAD = 60;@Overridepublic Student process(Student item) throws ValidationException {/*** 需要执行super.process(item)才会调用自定义校验器*/super.process(item);String chinaScore = item.getChinaScore();String mathScore = item.getMathScore();String englishScore = item.getEnglishScore();String name = item.getName();String phone = item.getPhone();if (GOOD <= Double.parseDouble(chinaScore) && GOOD <= Double.parseDouble(mathScore) && GOOD <= Double.parseDouble(englishScore)){log.info("{}同学三科成绩均为90以上,应该给予奖励", name);}if (BAD > Double.parseDouble(chinaScore) && BAD > Double.parseDouble(mathScore) && BAD > Double.parseDouble(englishScore)){log.info("{}同学三科成绩均不及格,建议通知家长,电话:{}", name,phone);}return item;}
}

8.job监听器

package com.test.batch.listen;import lombok.extern.slf4j.Slf4j;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobExecutionListener;/*** @author 1*/
@Slf4j
public class MyJobListener implements JobExecutionListener {@Overridepublic void beforeJob(JobExecution jobExecution) {log.info("job开始,id:{}",jobExecution.getJobId());}@Overridepublic void afterJob(JobExecution jobExecution) {log.info("id:{}",jobExecution.getJobId());}
}

9.读组件监听器

package com.test.batch.listen;import lombok.extern.slf4j.Slf4j;
import org.springframework.batch.core.ItemReadListener;import static java.lang.String.format;/*** @author 1*/
@Slf4j
public class MyReaderListener implements ItemReadListener {@Overridepublic void beforeRead() {}@Overridepublic void afterRead(Object o) {}@Overridepublic void onReadError(Exception e) {log.error("读取数据失败:{}",e);log.info("item error:"+format("%s%n", e.getMessage()));}
}

10.写组件监听器

package com.test.batch.listen;import com.test.batch.entity.Student;
import lombok.extern.slf4j.Slf4j;
import org.springframework.batch.core.ItemWriteListener;import java.util.List;import static java.lang.String.format;/*** @author 1*/
@Slf4j
public class MyWriteListener implements ItemWriteListener<Student> {@Overridepublic void beforeWrite(List<? extends Student> list) {}@Overridepublic void afterWrite(List<? extends Student> list) {}@Overridepublic void onWriteError(Exception e, List<? extends Student> list) {try {log.info(format("%s%n", e.getMessage()));for (Student message : list) {log.info(format("Failed writing Students : %s", message.toString()));}} catch (Exception ex) {log.error("format error :{}",ex);}}
}

11.字段校验

package com.test.batch.listen;import org.springframework.batch.item.validator.ValidationException;
import org.springframework.batch.item.validator.Validator;
import org.springframework.beans.factory.InitializingBean;import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.ValidatorFactory;
import java.util.Set;/*** @author 1*/
public class MyBeanValidator<T> implements Validator<T>, InitializingBean {private javax.validation.Validator validator;@Overridepublic void validate(T t) throws ValidationException {/*** 使用Validator的validate方法校验数据*/Set<ConstraintViolation<T>> constraintViolations =validator.validate(t);if (constraintViolations.size() > 0) {StringBuilder message = new StringBuilder();for (ConstraintViolation<T> constraintViolation : constraintViolations) {message.append(constraintViolation.getMessage() + "\n");}throw new ValidationException(message.toString());}}@Overridepublic void afterPropertiesSet() throws Exception {ValidatorFactory validatorFactory =Validation.buildDefaultValidatorFactory();validator = validatorFactory.usingContext().getValidator();}
}

12.接口

package com.test.batch.controller;import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.launch.support.SimpleJobLauncher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.Date;/*** @author 1*/
@RestController
@Slf4j
public class TestController {@AutowiredSimpleJobLauncher launcher;@Autowiredprivate Job job;@GetMapping("testJob")public ResponseEntity testJob(){try {//job添加参数,确保每个job都唯一JobParameters jobParameters = new JobParametersBuilder().addDate("date",new Date()).toJobParameters();launcher.run(job,jobParameters);}catch (Exception e){log.error("job error:{}",e);return ResponseEntity.ok(e.getMessage());}return ResponseEntity.ok("操作成功!!!");}
}

13.数据
在这里插入图片描述
14.运行后浏览器输入
http://localhost:8081/doc.html
或页面输入localhost:8081/testJob,文件内容成功写入数据库

相关文章:

springboot整合springbatch批处理

springboot整合springbatch实现批处理 简介项目搭建步骤 简介 项目搭建 参考博客【场景实战】Spring Boot Spring Batch 实现批处理任务&#xff0c;保姆级教程 步骤 1.建表 建表sql CREATE TABLE student (id int NOT NULL AUTO_INCREMENT,name varchar(100) NOT NULL C…...

答案解析——C语言—第2次作业:转义字符

本次作业的链接如下&#xff1a;C语言—第2次作业&#xff1a;转义字符 1.下面哪个不是C语言内置的数据类型&#xff1a; C char //字符数据类型short //短整型int //整形long //长整型long long //更长的整形float //单精度浮点数double //双精度浮点数 …...

HTML5-新增表单input属性

新增表单属性 form控件主要新增的属性: autocomplete 是否启用表单的自动完成功能&#xff0c;取值&#xff1a;on&#xff08;默认&#xff09;、off novalidate 提交表单时不进行校验&#xff0c;默认会进行表单校验 autocomplete属性 概念&#xff1a;autocomplete属性…...

css-、串联选择器和后代选择器的用法

& &表示嵌套的上一级&#xff0c;这是sass的语法&#xff0c;代表上一级选择器 .btn {&.primary {background-color: #007bff;color: #fff;} } 编译出来的结果是同一个元素&#xff0c;有两个类名&#xff0c;两个类名之间没有空格&#xff1a; .btn.primary {…...

nifi详细介绍--一款开箱即用、功能强大可靠,可用于处理和分发数据的大数据组件

目录 目录 一、引言 二、NiFi 的历史背景介绍 三、NiFi 是什么&#xff1f; 核心特性 应用领域 四、NIFI 入门 五 、NiFi 工作流程 六、实际应用场景 七、优势总结 一、引言 NiFi&#xff08;Apache NiFi&#xff09;&#xff0c;全名为“Niagara Files”&#xff0…...

K8S Dashboard登录Token过期问题处理

整体思路 用户访问一个页面&#xff0c;在该页面中设置一个超链接&#xff0c;点击跳转至K8S Dashboard&#xff1b;跳转后&#xff0c;使用剪贴板上已复制的Token粘贴到Dashboard页面中的输入框登录即可。 写个定时任务将Token复制到页面上&#xff0c;过期了重新再登…...

x-cmd pkg | trafilatura - 网络爬虫和搜索引擎优化工具

目录 简介首次用户技术特点竞品和相关作品进一步阅读 简介 trafilatura 是一个用于从网页上提取文本的命令行工具和 python 包: 提供网络爬虫、下载、抓取以及提取主要文本、元数据和评论等功能可帮助网站导航和从站点地图和提要中提取链接无需数据库&#xff0c;输出即可转换…...

前端知识点(面试可看) —— JS

摘要 马上就要毕业啦&#xff0c;没有参加2023年的秋招&#xff0c;准备在最近开始找全职或者实习工作&#xff0c;然后也马上过年了&#xff0c;总结和理一下自己的知识要点&#xff0c;参加2024年的春招。 1. JS的执行流程 浏览器的V8引擎收到到执行的JS代码V8结构化这段代…...

CSRF总结

CSRF 文章目录 CSRF漏洞原理漏洞危害漏洞防护CSRF攻击流程CSRF和XSS的区别CSRF漏洞挖掘及利用 CSRF 跨站点请求伪造&#xff08;CSRF&#xff09;攻击者会诱导受害者点击事先伪造好的url或者链接&#xff0c;点击后&#xff0c;攻击者就可以盗用你的身份&#xff0c;以你的身份…...

降维算法的简单介绍

降维算法 降维算法&#xff1a; 通过减少数据的维度&#xff0c;如主成分分析和 t-分布邻域嵌入等。 降维通俗的讲&#xff0c;是通过减少数据的维度来处理高维数据的过程。降维算法有助于消除数据中的冗余信息&#xff0c;减少噪声&#xff0c;并提高计算效率。以下是一些常见…...

k8s的声明式资源管理

在k8s当中支持两种声明资源的方式&#xff1a; 1、 yaml格式&#xff1a;主要用于和管理资源对象 2、 json格式&#xff1a;主要用于在API接口之间进行消息传递 声明式管理方法(yaml)文件 1、 适合对资源的修改操作 2、 声明式管理依赖于yaml文件&#xff0c;所有的内容都…...

Git | tag相关命令

语法命令 git tag -h usage: git tag [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>]<tagname> [<head>]or: git tag -d <tagname>...or: git tag -l [-n[<num>]] [--contains <commit>] [--no-contains <commit&g…...

【Java期末】学生成绩管理系统

诚接计算机专业编程任务(C语言、C、Python、Java、HTML、JavaScript、Vue等)10/15R&#xff0c;如有需要请私信我&#xff0c;或者加我的企鹅号&#xff1a;1404293476 本文资源下载地址&#xff1a;https://download.csdn.net/download/weixin_47040861/88697244 —————…...

顶顶通呼叫中心中间件通过队列外呼拨打另一个sip并且放音(mod_cti基于FreeSWITCH)

介绍 顶顶通呼叫中心中间件通过队列外呼拨打另一个sip并且放音 一、添加acl 打开ccadmin->点击配置文件->点击acl.conf->在</list>后面添加一条图中的信息->muqi是我自己设置的名字你们可以修改为自己需要的名字->添加好了点击提交XML->在运维调试点…...

SQL Server从0到1——报错注入

报错注入分为三类&#xff1a;隐式转换&#xff0c;和显示转换&#xff0c;declare函数 隐式转换&#xff1a; 原理&#xff1a;将不同数据类型的数据进行转换或对比 select * from test.dbo.users where (select user)>0 #对比 select * from test.dbo.users where ((sel…...

【python高级用法】线程

前言 Python通过标准库的 threading 模块来管理线程。这个模块提供了很多不错的特性&#xff0c;让线程变得无比简单。实际上&#xff0c;线程模块提供了几种同时运行的机制&#xff0c;实现起来非常简单。 线程模块 线程对象Lock对象RLock对象信号对象条件对象事件对象 简单…...

分布式高级知识点

分布式一致性算法: Paxos Paxos 是一种分布式一致性算法,用于在分布式系统中达成共识。它可以保证,即使在存在节点故障的情况下,系统也能就某个值达成一致。 Paxos 算法的基本思想是,首先选出一个协调者(leader)。协调者负责向其他节点发送提案(proposal)。其他节点收…...

Linux 命令之 dpkg 的简单使用

查询已安装的软件包及其依赖关系 dpkg -s name...

Ubuntu20.04服务器使用教程(安装教程、常用命令、故障排查)持续更新中.....

安装教程&#xff08;系统、NVIDIA驱动、CUDA、CUDNN、Pytorch、Timeshift、ToDesk&#xff09; 制作U盘启动盘&#xff0c;并安装系统 在MSDN i tell you下载Ubuntu20.04 Desktop 版本&#xff0c;并使用Rufus制作UEFI启动盘&#xff0c;参考UEFI安装Ubuntu使用GPTUEFI模式安…...

访问学者J1签证的申请流程

访问学者J1签证是许多人前往美国进行学术研究和文化交流的重要途径之一。申请J1签证需要经过一系列步骤和程序&#xff0c;让知识人网小编带大家来了解一下申请流程吧。 首先&#xff0c;申请者需要确认自己符合J1签证的资格要求。这包括被美国的赞助机构或组织接受&#xff0c…...

51单片机(STC8)-- GPIO输入输出

文章目录 I/O口相关寄存器端口数据寄存器端口模式配置寄存器&#xff08;PxM0&#xff0c;PxM1&#xff09;端口上拉电阻控制寄存器(PxPU)关于I/O的注意事项 配置I/O口I/O设置demoI/O端口模式LED控制&#xff08;I/O输出&#xff09;按键检测&#xff08;I/O输入&#xff09; S…...

【实用安装教程】在win系统下制作Mac OS镜像启动U盘

第一步&#xff1a;制作Mac OS系统引导镜像启动U盘 准备一个8G&#xff08;或以上&#xff09;的U盘插入到win系统的电脑上 去下载TransMac(Mac启动盘制作工具)v10.4按照说明安装好 插入准备好的U盘&#xff0c;U盘数据要转移&#xff0c;打开TransMac&#xff0c;右键U盘选…...

职场唠嗑-国家教学

文章目录 职场晋升潜规则&#xff1a;让上司看到自己工作能力职场生存指南&#xff1a;脆弱无罪&#xff0c;眼泪如何变利器关于具备谋取好职位的资格实习生在职场的基本“规矩”比能力更能决定人生的&#xff0c;是你对工作的态度跳槽&#xff1a;看别人家的“饭”端自家的碗职…...

【温故而知新】JavaScript数据结构详解

一、概念 JavaScript是一种弱类型的编程语言&#xff0c;它提供了一些内置的数据结构来存储和组织数据。 在计算机科学中&#xff0c;数据结构是一种特定的方式来组织和存储数据&#xff0c;以便于有效地访问和修改数据。在JavaScript中&#xff0c;数据结构是指相互之间存在…...

matlab如何标定相机内外参和畸变参数

关于内外参矩阵和畸变矩阵可以学习 https://blog.csdn.net/qq_30815237/article/details/87530011?spm1001.2014.3001.5506 在APP中找到 camera Calibrator 点击 Add Images&#xff0c;导入拍照图片。标定20张左右就够了&#xff0c;然后角度变一下&#xff0c;但不需要变太…...

【卫星科普】什么是农业一号卫星和农业二号卫星?

农业一号卫星和农业二号卫星是中国自主研发的两颗重要卫星&#xff0c;主要用于农业领域的监测和研究。 农业一号卫星是中国第一颗具备红边波段传感器的卫星&#xff0c;也是世界上第一颗具备红边波段的宽视场多光谱中高分辨率卫星。这对农业农村遥感监测非常重要&#xff0c;…...

imgaug库指南(一):从入门到精通的【图像增强】之旅

文章目录 引言imgaug简介安装和导入imgaug代码示例imgaug的强大之处和用途小结结尾 引言 在深度学习和计算机视觉的世界里&#xff0c;数据是模型训练的基石&#xff0c;其质量与数量直接影响着模型的性能。然而&#xff0c;获取大量高质量的标注数据往往需要耗费大量的时间和…...

vue封装基础input组件(添加防抖功能)

先看一下效果&#xff1a; // 调用页面 <template><div><!-- v-model&#xff1a;伪双向绑定 --><my-input v-model"inputVal" label"姓名" type"textarea" /></div> </template><script> import…...

小程序一次性订阅消息(消息通知):java服务端实现

文章目录 引言一、消息订阅1.1 小程序订阅消息功能介绍1.2 消息分类1.2.1 新版一次性订阅消息Beta1.2.2 一次性订阅消息&#xff08;用户通过弹窗订阅&#xff09;1.2.3 长期订阅消息&#xff08;用户通过弹窗订阅&#xff09;1.2.4 设备订阅消息 二、获取模板ID1.登录[微信公众…...

百度自由DIY小程序源码:PHP+MySQL组合开发 带完整的搭建教程

随着移动互联网的快速发展&#xff0c;小程序已成为企业与用户互动的重要平台。然而&#xff0c;对于许多中小企业和开发者来说&#xff0c;从零开始开发一款小程序需要投入大量的时间和资源。 以下是部分代码示例&#xff1a; 系统特色功能一览&#xff1a; 1.高度自定义&…...

家乐福官网/荥阳seo推广

昨天晚上在寝室写python多线程的时候&#xff0c;用了几个测试的程序&#xff0c;分别是递归方法求斐波那契数的值。分别采用单线程一个一个执行的方法和采用多线程调用的方法。观察所用的时间基本上差不多的。 然后我在每个函数内部加入sleep()函数以后&#xff0c;分别让它们…...

上海公司注册核名查询/黑帽seo教程

为什么80%的码农都做不了架构师&#xff1f;>>> 首先说一下Redis公认的特点&#xff1a; Redis支持数据的持久化&#xff0c;可以将内存中的数据保持在磁盘中&#xff0c;重启的时候可以再次加载进行使用。Redis不仅仅支持简单的key-value类型的数据&#xff0c;同…...

wordpress搜索功能加强/直播回放老卡怎么回事

PHP文章摘要生成方法(函数)文章生成摘要的方法有多种&#xff0c;可以用JS在客户端生成&#xff0c;也可以在服务器端生成&#xff0c;当然更不排除在数据库中加一个摘要字段&#xff0c;在发布文章的时候自行设置。以下是在服务器端生成时的方法。我们在写BLOG时经常需要显示文…...

11电影网/北京自动seo

AOP是什么&#xff1f;    AOP是OOP的延续&#xff0c;Aspect Oriented Programming的缩写&#xff0c;即面向方面编程。AOP是GoF设计模式的延续&#xff0c;设计模式追求的是调用者和被调用者之间的解耦&#xff0c;AOP也是这种目标的一 种实现。    案例:在应用程序中…...

扬州网络推广哪家好/seo优化思路

题意是说第一行字符串能否由第二行字符串经过“替代”和“位置转换”后得到。 做题时&#xff0c;实际上只统计两个字符串的各字符出现的“次数”是否相同即可&#xff08;不必计较这相同次数是否字符也相同&#xff09;。 算法思想如下&#xff1a; 1&#xff09;读入两行字符…...

现在做网站用的软件/关键词排名点击软件首页

博客地址&#xff1a;http://www.moonxy.com 一、前言 Elasticsearch 底层依赖于 Lucene 库&#xff0c;而 Lucene 库完全是 Java 编写的&#xff0c;前面的文章都是发送的 RESTful API 请求&#xff0c;其实这些请求最后还是通过 Java 执行的。RESTful API 能做的 Java API 都…...