詳解spring batch的使用和定時(shí)器Quart的使用
spring Batch是一個(gè)基于Spring的企業(yè)級(jí)批處理框架,它通過(guò)配合定時(shí)器Quartz來(lái)輕易實(shí)現(xiàn)大批量的數(shù)據(jù)讀取或插入,并且全程自動(dòng)化,無(wú)需人員管理。
在使用spring batch之前,得對(duì)spring batch的流程有一個(gè)基本了解
每個(gè)batch它都包含了一個(gè)job,而一個(gè)job中卻有可能包含多個(gè)step,整個(gè)batch中干活的是step,batch主要是用來(lái)對(duì)數(shù)據(jù)的操作,所以step就有三個(gè)操作數(shù)據(jù)的東西,一個(gè)是ItemReader用來(lái)讀取數(shù)據(jù)的,一個(gè)是ItemProcessor用來(lái)處理數(shù)據(jù)的,一個(gè)是ItemWriter用來(lái)寫(xiě)數(shù)據(jù)(可以是文件也可以是插入sql語(yǔ)句),JobLauncher用來(lái)啟動(dòng)Job,JobRepository是上述處理提供的一種持久化機(jī)制,它為JobLauncher,Job,和Step實(shí)例提供CRUD操作。
pom.xml 三個(gè)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> <!--一個(gè)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的讀取數(shù)據(jù)操作--> <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>
讀取數(shù)據(jù) 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; } }
處理數(shù)據(jù) teacherInterviewProcessor ,這個(gè)處理數(shù)據(jù)方法,一般都是在這里在這里進(jìn)行一些數(shù)據(jù)的加工,比如有些數(shù)據(jù)沒(méi)有讀到,你也可以在這個(gè)方法和后面那個(gè)寫(xiě)入數(shù)據(jù)的類里面寫(xiě),所以就導(dǎo)致了這個(gè)類里面你可以什么都不敢,直接把數(shù)據(jù)拋到后面去,讓后面的寫(xiě)數(shù)據(jù)類來(lái)處理;我這里就是處理數(shù)據(jù)的這個(gè)類什么都沒(méi)寫(xiě),但是最好還是按它的規(guī)則來(lái)!
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; //業(yè)務(wù)層 @Component("teacherInterviewProcessor") public class TeacherInterviewProcessor implements ItemProcessor<TeacherInterviewdetail, TeacherInterviewdetail> { @Override public TeacherInterviewdetail process(TeacherInterviewdetail teacherInterviewdetail) throws Exception { return teacherInterviewdetail; } }
寫(xiě)數(shù)據(jù) teacherInterviewItemWriter 這個(gè)類里面主要是把數(shù)據(jù)寫(xiě)進(jìn)一個(gè)文件里,同時(shí)我這個(gè)類里面還有一些數(shù)據(jù)處理
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; //寫(xiě) @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 ); } }
我這里有用到一個(gè)吧數(shù)據(jù)寫(xiě)進(jìn)CSV文件的jar包
<dependency> <groupId>net.sourceforge.javacsv</groupId> <artifactId>javacsv</artifactId> <version>2.0</version> </dependency>
CsvUtils幫助類的寫(xiě)入CSV文件方法
/** * 寫(xiě)入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(); } }
就這樣一個(gè)基本的batch流程就跑起來(lái)了,它通過(guò)從數(shù)據(jù)里讀取一些數(shù)據(jù),然后經(jīng)過(guò)處理后,被存進(jìn)服務(wù)器下的一個(gè)文件里面,之后像這種數(shù)據(jù)的讀取就不需要去數(shù)據(jù)庫(kù)里面查詢了,而是可以直接通過(guò)讀取CSV文件來(lái)處理這個(gè)業(yè)務(wù)。一般使用這個(gè)的都會(huì)配一個(gè)定時(shí)器,讓它們每隔一段時(shí)間跑一次,從而獲得較新的數(shù)據(jù)
下面是定時(shí)器的配置
定時(shí)器的配置非常簡(jiǎn)單,我是使用注解方式來(lái)配置的
定時(shí)器任務(wù)類
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;//教師訪談?dòng)涗? public void setTeacherInterviewBatch(TeacherInterviewBatch teacherInterviewBatch) { this.teacherInterviewBatch = teacherInterviewBatch; } @Scheduled(cron= "0 30 22 * * ?") //每天晚上十點(diǎn)30執(zhí)行一次 這個(gè)注解會(huì)讓框架會(huì)自動(dòng)把這個(gè)方法看成任務(wù)啟動(dòng)方法 @Override public void task() { try { teacherInterviewBatch.test();//教師訪談 } catch (Exception e) { e.printStackTrace(); } } }
定時(shí)器所真正要執(zhí)行的方法
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; }
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Java中批處理框架spring batch詳細(xì)介紹
- 詳解SpringBoot和SpringBatch 使用
- 基于Spring Batch向Elasticsearch批量導(dǎo)入數(shù)據(jù)示例
- 詳解Spring batch 入門(mén)學(xué)習(xí)教程(附源碼)
- 淺談Spring Batch在大型企業(yè)中的最佳實(shí)踐
- Spring Batch入門(mén)教程篇
- Spring Batch讀取txt文件并寫(xiě)入數(shù)據(jù)庫(kù)的方法教程
- Spring batch批處理框架
- spring batch 讀取多個(gè)文件數(shù)據(jù)導(dǎo)入數(shù)據(jù)庫(kù)示例
- 詳解批處理框架之Spring Batch
相關(guān)文章
SpringBoot2整合Drools規(guī)則引擎及案例詳解
這篇文章主要介紹了SpringBoot2整合Drools規(guī)則引擎及案例詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-10-10SpringCloud容器化服務(wù)發(fā)現(xiàn)及注冊(cè)實(shí)現(xiàn)方法解析
這篇文章主要介紹了SpringCloud容器化服務(wù)發(fā)現(xiàn)及注冊(cè)實(shí)現(xiàn)方法解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08JAVA中使用FTPClient實(shí)現(xiàn)文件上傳下載實(shí)例代碼
本文給大家介紹如何利用jakarta commons中的FTPClient(在commons-net包中)實(shí)現(xiàn)上傳下載文件。非常不錯(cuò)具有參考借鑒價(jià)值,感興趣的朋友一起學(xué)習(xí)吧2016-06-06java 學(xué)習(xí)筆記(入門(mén)篇)_java程序helloWorld
安裝配置完Java的jdk,下面就開(kāi)始寫(xiě)第一個(gè)java程序--hello World.用來(lái)在控制臺(tái)輸出“Hello World”,接下來(lái)詳細(xì)介紹,感興趣的朋友可以參考下2013-01-01Tomcat集群和Session復(fù)制應(yīng)用介紹
本文將詳細(xì)介紹Tomcat集群和Session復(fù)制應(yīng)用,需要了解的朋友可以參考下2012-11-11Spring Boot項(xiàng)目打包指定包名實(shí)現(xiàn)示例
這篇文章主要為大家介紹了Spring Boot項(xiàng)目打包指定包名實(shí)現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11