zoukankan      html  css  js  c++  java
  • spring batch的使用和定时器Quart的使用

     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包

    [html] view plain copy
    1. <span style="white-space:pre;">     </span><dependency>  
    2.          <groupId>org.springframework</groupId>  
    3.          <artifactId>spring-batch-core</artifactId>  
    4.          <version>2.1.8.RELEASE</version>  
    5.         </dependency>  
    6.           
    7.         <dependency>  
    8.           <groupId>org.springframework</groupId>  
    9.           <artifactId>spring-batch-infrastructure</artifactId>  
    10.           <version>2.1.8.RELEASE</version>  
    11.     <span style="white-space:pre;"</span></dependency>  
    12.           
    13.          <dependency>  
    14.           <groupId>org.springframework</groupId>  
    15.           <artifactId>spring-batch-test</artifactId>  
    16.           <version>2.1.8.RELEASE</version>  
    17.         </dependency>    

    batch.xml

    [html] view plain copy
    1. <beans xmlns="http://www.springframework.org/schema/beans"  
    2.     xmlns:batch="http://www.springframework.org/schema/batch" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    3.     xsi:schemaLocation="http://www.springframework.org/schema/batch  
    4.         http://www.springframework.org/schema/batch/spring-batch-2.1.xsd  
    5.         http://www.springframework.org/schema/beans   
    6.         http://www.springframework.org/schema/beans/spring-beans-3.1.xsd  
    7.     ">  
    8.   
    9.   
    10.     <bean id="jobLauncher"  
    11.         class="org.springframework.batch.core.launch.support.SimpleJobLauncher">  
    12.         <property name="jobRepository" ref="jobRepository" />  
    13.     </bean>  
    14.   
    15.     <bean id="jobRepository"  
    16.         class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean">  
    17.         <property name="validateTransactionState" value="false" />  
    18.   
    19.     </bean>  
    20. <span style="white-space:pre;">     </span><!--一个job-->  
    21.         <batch:job id="writerteacherInterview">  
    22.                 <batch:step id="teacherInterview">  
    23.                     <batch:tasklet>  
    24.                         <batch:chunk reader="jdbcItemReaderTeacherInterview" writer="teacherInterviewItemWriter"  
    25.                             processor="teacherInterviewProcessor" commit-interval="10">  
    26.                         </batch:chunk>  
    27.                     </batch:tasklet>  
    28.                 </batch:step>  
    29.             </batch:job>  
    30.   
    31.   
    32.   
    33.   
    34.   
    35.     <!--job的读取数据操作-->  
    36.     <bean id="jdbcItemReaderTeacherInterview"  
    37.         class="org.springframework.batch.item.database.JdbcCursorItemReader"  
    38.         scope="step">  
    39.         <property name="dataSource" ref="dataSource" />  
    40.         <property name="sql"  
    41.             value="select distinct teacherName ,count(teacherName) as num from examininterviewrecord   where pdate >'${detail_startime}' and pdate < '${detail_endtime}'  GROUP BY teacherName " />  
    42.         <property name="rowMapper" ref="teacherInterviewMapper">  
    43.         </property>  
    44.     </bean>  
    45.   
    46.   
    47. </beans>  

    读取数据    teacherInterviewMapper

    [java] view plain copy
    1. package com.yc.batch;  
    2.   
    3. import java.sql.ResultSet;  
    4. import java.sql.SQLException;  
    5. import org.springframework.jdbc.core.RowMapper;  
    6. import org.springframework.stereotype.Component;  
    7. import com.yc.vo.TeacherInterviewdetail;  
    8. import com.yc.vo.TeacherWorkdetail;  
    9. import com.yc.vo.Workdetail;  
    10. @Component("teacherInterviewMapper")    
    11. public class TeacherInterviewMapper implements RowMapper {    
    12.     @Override  
    13.     public Object mapRow(ResultSet rs, int rowNum) throws SQLException {    
    14.           
    15.         TeacherInterviewdetail TId=new TeacherInterviewdetail();  
    16.         TId.setTeacherName(rs.getString("teacherName"));  
    17.          TId.setNum(rs.getInt("num"));  
    18.         return TId;    
    19.     }  
    20. }   

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

    [java] view plain copy
    1. package com.yc.batch;  
    2.   
    3. import org.hibernate.engine.transaction.jta.platform.internal.SynchronizationRegistryBasedSynchronizationStrategy;  
    4. import org.springframework.batch.item.ItemProcessor;  
    5. import org.springframework.stereotype.Component;  
    6. import org.springframework.stereotype.Service;  
    7.   
    8. import com.yc.vo.TeacherInterviewdetail;  
    9. import com.yc.vo.TeacherWorkdetail;  
    10. import com.yc.vo.Workdetail;  
    11.   
    12.   
    13. //业务层  
    14. @Component("teacherInterviewProcessor")  
    15. public class TeacherInterviewProcessor implements ItemProcessor<TeacherInterviewdetail, TeacherInterviewdetail> {  
    16.   
    17.     @Override  
    18.     public TeacherInterviewdetail process(TeacherInterviewdetail teacherInterviewdetail) throws Exception {  
    19.            
    20.         return teacherInterviewdetail;  
    21.     }  
    22. }  

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

    [java] view plain copy
    1. package com.yc.batch;  
    2.   
    3. import java.io.InputStream;  
    4.   
    5. import java.text.NumberFormat;  
    6. import java.util.ArrayList;  
    7. import java.util.List;  
    8. import java.util.Properties;  
    9. import javax.annotation.Resource;  
    10. import org.springframework.batch.item.ItemWriter;  
    11. import org.springframework.stereotype.Component;  
    12. import org.springframework.stereotype.Service;  
    13. import com.yc.biz.ExamineeClassBiz;  
    14. import com.yc.biz.WorkBiz;  
    15. import com.yc.utils.CsvUtils;  
    16. import com.yc.vo.TeacherInterviewdetail;  
    17. import com.yc.vo.TeacherWorkdetail;  
    18. import com.yc.vo.Workdetail;  
    19. import net.sf.ehcache.util.PropertyUtil;  
    20. //写  
    21. @Component("teacherInterviewItemWriter")  
    22. public class TeacherInterviewItemWriter implements ItemWriter<TeacherInterviewdetail>{  
    23.   
    24.     @Override  
    25.     public void write(List<? extends TeacherInterviewdetail> teacherInterviewdetails) throws Exception {  
    26.         Properties props = new Properties();  
    27.         InputStream in= PropertyUtil.class.getClassLoader().getResourceAsStream("connectionConfig.properties");  
    28.         props.load(in);  
    29.         String time=props.getProperty("detail_time");  
    30.         CsvUtils cu=new CsvUtils();  
    31.          List<Object> works=new ArrayList<Object>();  
    32.          for(TeacherInterviewdetail t:teacherInterviewdetails){  
    33.              works.add(t);  
    34.          }  
    35.            
    36.         String path=this.getClass().getResource("/").getPath();  
    37.         path=path.substring(0,path.lastIndexOf("/"));  
    38.         path=path.substring(0,path.lastIndexOf("/"));  
    39.         path=path.substring(0,path.lastIndexOf("/"));  
    40.         path=path.substring(0,path.lastIndexOf("/"));  
    41.         cu.writeCsv(path+"/csv/teacherInterview_"+time+".csv",works );    
    42.     }   
    43. }  


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

    [html] view plain copy
    1. <span style="white-space:pre;">         </span><dependency>  
    2.           <groupId>net.sourceforge.javacsv</groupId>  
    3.           <artifactId>javacsv</artifactId>  
    4.           <version>2.0</version>  
    5.         </dependency>  

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

    [cpp] view plain copy
    1. /**  
    2.      * 写入CSV文件  
    3.      * @throws IOException  
    4.      */    
    5.     public void writeCsv(String path,List<Object> t) throws IOException{    
    6.         String csvFilePath = path;  
    7.         String filepath=path.substring(0,path.lastIndexOf("/"));  
    8.         File f=new File(filepath);  
    9.         if(!f.exists()){  
    10.             f.mkdirs();  
    11.         }  
    12.         File file=new File(path);  
    13.         if(!file.exists()){  
    14.             file.createNewFile();  
    15.         }  
    16.         CsvWriter wr =new CsvWriter(csvFilePath,',',Charset.forName("GBK"));  
    17.         try {   
    18.             for(Object obj:t){  
    19.                 String[] contents=obj.toString().split(",");  
    20.                 wr.writeRecord(contents);    
    21.             }  
    22.             wr.close();    
    23.         } catch (IOException e) {    
    24.             e.printStackTrace();    
    25.         }    
    26.     }    


    就这样一个基本的batch流程就跑起来了,它通过从数据里读取一些数据,然后经过处理后,被存进服务器下的一个文件里面,之后像这种数据的读取就不需要去数据库里面

    查询了,而是可以直接通过读取CSV文件来处理这个业务。一般使用这个的都会配一个定时器,让它们每隔一段时间跑一次,从而获得较新的数据

    下面是定时器的配置

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

    定时器任务类

    [java] view plain copy
    1. package com.yc.task.impl;  
    2. import javax.transaction.Transactional;  
    3. import org.springframework.batch.core.JobParametersInvalidException;  
    4. import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;  
    5. import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException;  
    6. import org.springframework.batch.core.repository.JobRestartException;  
    7. import org.springframework.batch.item.ItemProcessor;  
    8. import org.springframework.beans.factory.annotation.Autowired;  
    9. import org.springframework.scheduling.annotation.Scheduled;  
    10. import org.springframework.stereotype.Component;  
    11. import org.springframework.stereotype.Service;  
    12.   
    13. import com.yc.batch.ClassBatch;  
    14. import com.yc.batch.MessageItemBatch;  
    15. import com.yc.batch.TeacherInterviewBatch;  
    16. import com.yc.batch.TearcherBatch;  
    17. import com.yc.po.Work;  
    18. import com.yc.task.WorkTask;  
    19. import com.yc.vo.Workdetail;  
    20. @Service  
    21. public class WorkTaskImpl implements WorkTask{  
    22.   
    23.     @Autowired  
    24.     private TeacherInterviewBatch teacherInterviewBatch;//教师访谈记录  
    25.     public void setTeacherInterviewBatch(TeacherInterviewBatch teacherInterviewBatch) {  
    26.         this.teacherInterviewBatch = teacherInterviewBatch;  
    27.     }  
    28.       
    29.     @Scheduled(cron= "0 30 22 * * ?")   //每天晚上十点30执行一次  这个注解会让框架会自动把这个方法看成任务启动方法   
    30.     @Override  
    31.     public void task() {  
    32.         try {  
    33.             teacherInterviewBatch.test();//教师访谈  
    34.         } catch (Exception e) {  
    35.             e.printStackTrace();  
    36.         }  
    37.           
    38.     }  
    39.   
    40. }  

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

    [java] view plain copy
    1. package com.yc.batch;  
    2.   
    3. import javax.annotation.Resource;  
    4. import org.apache.commons.jexl2.Main;  
    5. import org.springframework.batch.core.Job;  
    6. import org.springframework.batch.core.JobExecution;  
    7. import org.springframework.batch.core.JobParameters;  
    8. import org.springframework.batch.core.JobParametersBuilder;  
    9. import org.springframework.batch.core.JobParametersInvalidException;  
    10. import org.springframework.batch.core.launch.JobLauncher;  
    11. import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;  
    12. import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException;  
    13. import org.springframework.batch.core.repository.JobRestartException;  
    14. import org.springframework.beans.factory.annotation.Autowired;  
    15. import org.springframework.stereotype.Component;  
    16.   
    17. @Component  
    18. public class TeacherInterviewBatch {  
    19.   
    20.     private Job job;  
    21.     private JobLauncher launcher;  
    22.   
    23.     @Resource(name="writerteacherInterview")  
    24.     public void setJob(Job job) {  
    25.         this.job = job;  
    26.     }  
    27.   
    28.     @Autowired   
    29.     public void setLauncher(JobLauncher launcher) {  
    30.         this.launcher = launcher;  
    31.     }  
    32.   
    33.   
    34.     public void test() throws JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException, JobParametersInvalidException{  
    35.   
    36.         JobParameters jobParameters =  
    37.                 new JobParametersBuilder()  
    38.                 .addLong("time",System.currentTimeMillis()).toJobParameters();  
    39.   
    40.         JobExecution result = launcher.run(job, jobParameters);  
    41.     }  
    42.   
    43. }  


    就这样batch就被定时器调度起来了,每天十点准时使用batch来操作数据

    转自:https://blog.csdn.net/pttaoge/article/details/76684656

  • 相关阅读:
    枚举显示中文问题
    各种计算机体系结构的特点与应用(SMP、MPP等)
    Redis应用
    如果是除去末尾特定字符或字符串:TrimEnd方法性能优于Remove方法
    N笔试题
    PropertyGrid中的枚举显示为中文
    【1.2.3】操作系统性能优化
    【T4实践(一)】模板生成代码入门
    构成计算机的各类部件的功能及其相互关系
    net中String是引用类型还是值类型
  • 原文地址:https://www.cnblogs.com/Gent-Wang/p/8901012.html
Copyright © 2011-2022 走看看