详解spring batch的使用和定时器Quart的使用

发布时间 - 2026-01-11 02:40:14    点击率:

spring Batch是一个基于Spring的企业级批处理框架,它通过配合定时器Quartz来轻易实现大批量的数据读取或插入,并且全程自动化,无需人员管理。

在使用spring batch之前,得对spring batch的流程有一个基本了解

每个batch它都包含了一个job,而一个job中却有可能包含多个step,整个batch中干活的是step,batch主要是用来对数据的操作,所以step就有三个操作数据的东西,一个是ItemReader用来读取数据的,一个是ItemProcessor用来处理数据的,一个是ItemWriter用来写数据(可以是文件也可以是插入sql语句),JobLauncher用来启动Job,JobRepository是上述处理提供的一种持久化机制,它为JobLauncher,Job,和Step实例提供CRUD操作。

pom.xml  三个batch的jar包

<dependency> 
     <groupId>org.springframework</groupId> 
     <artifactId>spring-batch-core</artifactId> 
     <version>2.1.8.RELEASE</version> 
    </dependency> 
     
    <dependency> 
     <groupId>org.springframework</groupId> 
     <artifactId>spring-batch-infrastructure</artifactId> 
     <version>2.1.8.RELEASE</version> 
<dependency> 
     
     <dependency> 
     <groupId>org.springframework</groupId> 
     <artifactId>spring-batch-test</artifactId> 
     <version>2.1.8.RELEASE</version> 
    </dependency>  

batch.xml

<beans xmlns="http://www.springframework.org/schema/beans" 
  xmlns:batch="http://www.springframework.org/schema/batch" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xsi:schemaLocation="http://www.springframework.org/schema/batch 
    http://www.springframework.org/schema/batch/spring-batch-2.1.xsd 
    http://www.springframework.org/schema/beans  
    http://www.springframework.org/schema/beans/spring-beans-3.1.xsd 
  "> 
 
 
  <bean id="jobLauncher" 
    class="org.springframework.batch.core.launch.support.SimpleJobLauncher"> 
    <property name="jobRepository" ref="jobRepository" /> 
  </bean> 
 
  <bean id="jobRepository" 
    class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean"> 
    <property name="validateTransactionState" value="false" /> 
 
  </bean> 
<!--一个job--> 
    <batch:job id="writerteacherInterview"> 
        <batch:step id="teacherInterview"> 
          <batch:tasklet> 
            <batch:chunk reader="jdbcItemReaderTeacherInterview" writer="teacherInterviewItemWriter" 
              processor="teacherInterviewProcessor" commit-interval="10"> 
            </batch:chunk> 
          </batch:tasklet> 
        </batch:step> 
      </batch:job> 
 
 
 
 
 
  <!--job的读取数据操作--> 
  <bean id="jdbcItemReaderTeacherInterview" 
    class="org.springframework.batch.item.database.JdbcCursorItemReader" 
    scope="step"> 
    <property name="dataSource" ref="dataSource" /> 
    <property name="sql" 
      value="select distinct teacherName ,count(teacherName) as num from examininterviewrecord  where pdate >'${detail_startime}' and pdate < '${detail_endtime}' GROUP BY teacherName " /> 
    <property name="rowMapper" ref="teacherInterviewMapper"> 
    </property> 
  </bean> 
 
 
</beans> 

读取数据    teacherInterviewMapper

package com.yc.batch; 
 
import java.sql.ResultSet; 
import java.sql.SQLException; 
import org.springframework.jdbc.core.RowMapper; 
import org.springframework.stereotype.Component; 
import com.yc.vo.TeacherInterviewdetail; 
import com.yc.vo.TeacherWorkdetail; 
import com.yc.vo.Workdetail; 
@Component("teacherInterviewMapper")  
public class TeacherInterviewMapper implements RowMapper {  
  @Override 
  public Object mapRow(ResultSet rs, int rowNum) throws SQLException {  
     
    TeacherInterviewdetail TId=new TeacherInterviewdetail(); 
    TId.setTeacherName(rs.getString("teacherName")); 
     TId.setNum(rs.getInt("num")); 
    return TId;  
  } 
}  

处理数据  teacherInterviewProcessor ,这个处理数据方法,一般都是在这里在这里进行一些数据的加工,比如有些数据没有读到,你也可以在这个方法和后面那个写入数据的类里面写,所以就导致了这个类里面你可以什么都不敢,直接把数据抛到后面去,让后面的写数据类来处理;我这里就是处理数据的这个类什么都没写,但是最好还是按它的规则来!

package com.yc.batch; 
 
import org.hibernate.engine.transaction.jta.platform.internal.SynchronizationRegistryBasedSynchronizationStrategy; 
import org.springframework.batch.item.ItemProcessor; 
import org.springframework.stereotype.Component; 
import org.springframework.stereotype.Service; 
 
import com.yc.vo.TeacherInterviewdetail; 
import com.yc.vo.TeacherWorkdetail; 
import com.yc.vo.Workdetail; 
 
 
//业务层 
@Component("teacherInterviewProcessor") 
public class TeacherInterviewProcessor implements ItemProcessor<TeacherInterviewdetail, TeacherInterviewdetail> { 
 
  @Override 
  public TeacherInterviewdetail process(TeacherInterviewdetail teacherInterviewdetail) throws Exception { 
      
    return teacherInterviewdetail; 
  } 
} 

写数据 teacherInterviewItemWriter 这个类里面主要是把数据写进一个文件里,同时我这个类里面还有一些数据处理

package com.yc.batch; 
 
import java.io.InputStream; 
 
import java.text.NumberFormat; 
import java.util.ArrayList; 
import java.util.List; 
import java.util.Properties; 
import javax.annotation.Resource; 
import org.springframework.batch.item.ItemWriter; 
import org.springframework.stereotype.Component; 
import org.springframework.stereotype.Service; 
import com.yc.biz.ExamineeClassBiz; 
import com.yc.biz.WorkBiz; 
import com.yc.utils.CsvUtils; 
import com.yc.vo.TeacherInterviewdetail; 
import com.yc.vo.TeacherWorkdetail; 
import com.yc.vo.Workdetail; 
import net.sf.ehcache.util.PropertyUtil; 
//写 
@Component("teacherInterviewItemWriter") 
public class TeacherInterviewItemWriter implements ItemWriter<TeacherInterviewdetail>{ 
 
  @Override 
  public void write(List<? extends TeacherInterviewdetail> teacherInterviewdetails) throws Exception { 
    Properties props = new Properties(); 
    InputStream in= PropertyUtil.class.getClassLoader().getResourceAsStream("connectionConfig.properties"); 
    props.load(in); 
    String time=props.getProperty("detail_time"); 
    CsvUtils cu=new CsvUtils(); 
     List<Object> works=new ArrayList<Object>(); 
     for(TeacherInterviewdetail t:teacherInterviewdetails){ 
       works.add(t); 
     } 
      
    String path=this.getClass().getResource("/").getPath(); 
    path=path.substring(0,path.lastIndexOf("/")); 
    path=path.substring(0,path.lastIndexOf("/")); 
    path=path.substring(0,path.lastIndexOf("/")); 
    path=path.substring(0,path.lastIndexOf("/")); 
    cu.writeCsv(path+"/csv/teacherInterview_"+time+".csv",works );  
  }  
} 

我这里有用到一个吧数据写进CSV文件的jar包

<dependency> 
     <groupId>net.sourceforge.javacsv</groupId> 
     <artifactId>javacsv</artifactId> 
     <version>2.0</version> 
    </dependency> 

CsvUtils帮助类的写入CSV文件方法

/** 
   * 写入CSV文件 
   * @throws IOException 
   */  
  public void writeCsv(String path,List<Object> t) throws IOException{  
    String csvFilePath = path; 
    String filepath=path.substring(0,path.lastIndexOf("/")); 
    File f=new File(filepath); 
    if(!f.exists()){ 
      f.mkdirs(); 
    } 
    File file=new File(path); 
    if(!file.exists()){ 
      file.createNewFile(); 
    } 
    CsvWriter wr =new CsvWriter(csvFilePath,',',Charset.forName("GBK")); 
    try {  
      for(Object obj:t){ 
        String[] contents=obj.toString().split(","); 
        wr.writeRecord(contents);  
      } 
      wr.close();  
    } catch (IOException e) {  
      e.printStackTrace();  
    }  
  }  

就这样一个基本的batch流程就跑起来了,它通过从数据里读取一些数据,然后经过处理后,被存进服务器下的一个文件里面,之后像这种数据的读取就不需要去数据库里面查询了,而是可以直接通过读取CSV文件来处理这个业务。一般使用这个的都会配一个定时器,让它们每隔一段时间跑一次,从而获得较新的数据

下面是定时器的配置

定时器的配置非常简单,我是使用注解方式来配置的

定时器任务类

package com.yc.task.impl; 
import javax.transaction.Transactional; 
import org.springframework.batch.core.JobParametersInvalidException; 
import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException; 
import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException; 
import org.springframework.batch.core.repository.JobRestartException; 
import org.springframework.batch.item.ItemProcessor; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.scheduling.annotation.Scheduled; 
import org.springframework.stereotype.Component; 
import org.springframework.stereotype.Service; 
 
import com.yc.batch.ClassBatch; 
import com.yc.batch.MessageItemBatch; 
import com.yc.batch.TeacherInterviewBatch; 
import com.yc.batch.TearcherBatch; 
import com.yc.po.Work; 
import com.yc.task.WorkTask; 
import com.yc.vo.Workdetail; 
@Service 
public class WorkTaskImpl implements WorkTask{ 
 
  @Autowired 
  private TeacherInterviewBatch teacherInterviewBatch;//教师访谈记录 
  public void setTeacherInterviewBatch(TeacherInterviewBatch teacherInterviewBatch) { 
    this.teacherInterviewBatch = teacherInterviewBatch; 
  } 
   
  @Scheduled(cron= "0 30 22 * * ?")  //每天晚上十点30执行一次 这个注解会让框架会自动把这个方法看成任务启动方法  
  @Override 
  public void task() { 
    try { 
      teacherInterviewBatch.test();//教师访谈 
    } catch (Exception e) { 
      e.printStackTrace(); 
    } 
     
  } 
 
} 

定时器所真正要执行的方法

package com.yc.batch; 
 
import javax.annotation.Resource; 
import org.apache.commons.jexl2.Main; 
import org.springframework.batch.core.Job; 
import org.springframework.batch.core.JobExecution; 
import org.springframework.batch.core.JobParameters; 
import org.springframework.batch.core.JobParametersBuilder; 
import org.springframework.batch.core.JobParametersInvalidException; 
import org.springframework.batch.core.launch.JobLauncher; 
import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException; 
import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException; 
import org.springframework.batch.core.repository.JobRestartException; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.stereotype.Component; 
 
@Component 
public class TeacherInterviewBatch { 
 
  private Job job; 
  private JobLauncher launcher; 
 
  @Resource(name="writerteacherInterview") 
  public void setJob(Job job) { 
    this.job = job; 
  } 
 
  @Autowired  
  public void setLauncher(JobLauncher launcher) { 
    this.launcher = launcher; 
  } 

  以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


# spring  # batch  # 定时器  # quartz  # 使用  # Java中批处理框架spring batch详细介绍  # 详解SpringBoot和SpringBatch 使用  # 基于Spring Batch向Elasticsearch批量导入数据示例  # 详解Spring batch 入门学习教程(附源码)  # 浅谈Spring Batch在大型企业中的最佳实践  # Spring Batch入门教程篇  # Spring Batch读取txt文件并写入数据库的方法教程  # Spring batch批处理框架  # spring batch 读取多个文件数据导入数据库示例  # 详解批处理框架之Spring Batch  # 在这里  # 写进  # 的是  # 都是  # 是一个  # 我是  # 在这个  # 你可以  # 多个  # 有可能  # 就有  # 要去  # 批处理  # 这样一个  # 会让  # 可以直接  # 数据处理  # 不需  # 还有一些  # 你也可以 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 青岛网站建设如何选择本地服务器?  Laravel如何使用软删除(Soft Deletes)功能_Eloquent软删除与数据恢复方法  猎豹浏览器开发者工具怎么打开 猎豹浏览器F12调试工具使用【前端必备】  php结合redis实现高并发下的抢购、秒杀功能的实例  android nfc常用标签读取总结  网页制作模板网站推荐,网页设计海报之类的素材哪里好?  如何用手机制作网站和网页,手机移动端的网站能制作成中英双语的吗?  今日头条AI怎样推荐抢票工具_今日头条AI抢票工具推荐算法与筛选【技巧】  Laravel如何实现模型的全局作用域?(Global Scope示例)  Python文本处理实践_日志清洗解析【指导】  Laravel如何使用Seeder填充数据_Laravel模型工厂Factory批量生成测试数据【方法】  如何获取免费开源的自助建站系统源码?  网站设计制作书签怎么做,怎样将网页添加到书签/主页书签/桌面?  Laravel路由Route怎么设置_Laravel基础路由定义与参数传递规则【详解】  宙斯浏览器视频悬浮窗怎么开启 边看视频边操作其他应用教程  Laravel如何实现一对一模型关联?(Eloquent示例)  如何在香港服务器上快速搭建免备案网站?  无锡营销型网站制作公司,无锡网选车牌流程?  Laravel API资源(Resource)怎么用_格式化Laravel API响应的最佳实践  头像制作网站在线观看,除了站酷,还有哪些比较好的设计网站?  千库网官网入口推荐 千库网设计创意平台入口  Laravel用户认证怎么做_Laravel Breeze脚手架快速实现登录注册功能  Laravel如何使用Laravel Vite编译前端_Laravel10以上版本前端静态资源管理【教程】  教你用AI将一段旋律扩展成一首完整的曲子  如何在建站之星网店版论坛获取技术支持?  javascript基于原型链的继承及call和apply函数用法分析  图册素材网站设计制作软件,图册的导出方式有几种?  Edge浏览器提示“由你的组织管理”怎么解决_去除浏览器托管提示【修复】  nodejs redis 发布订阅机制封装实现方法及实例代码  百度浏览器ai对话怎么关 百度浏览器ai聊天窗口隐藏  Bootstrap整体框架之JavaScript插件架构  免费的流程图制作网站有哪些,2025年教师初级职称申报网上流程?  Laravel如何使用Guzzle调用外部接口_Laravel发起HTTP请求与JSON数据解析【详解】  JavaScript如何实现路由_前端路由原理是什么  html5audio标签播放结束怎么触发事件_onended回调方法【教程】  如何在IIS中新建站点并配置端口与IP地址?  PHP 实现电台节目表的智能时间匹配与今日/明日轮播逻辑  如何在宝塔面板中创建新站点?  Laravel DB事务怎么使用_Laravel数据库事务回滚操作  如何挑选优质建站一级代理提升网站排名?  iOS验证手机号的正则表达式  JavaScript Ajax实现异步通信  ,怎么在广州志愿者网站注册?  javascript中数组(Array)对象和字符串(String)对象的常用方法总结  哪家制作企业网站好,开办像阿里巴巴那样的网络公司和网站要怎么做?  Laravel中的withCount方法怎么高效统计关联模型数量  微信公众帐号开发教程之图文消息全攻略  如何在Windows服务器上快速搭建网站?  Laravel中间件起什么作用_Laravel Middleware请求生命周期与自定义详解  Laravel怎么实现支付功能_Laravel集成支付宝微信支付