spring batch
生活随笔
收集整理的這篇文章主要介紹了
spring batch
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
?http://www.4ucode.com/Study/Topic/478358
DelimitedLineTokenizer 的delimiter 默認是逗號','.names is as the fieldMap keys, it's not the header of feed file
FixedLengthTokenizer use the column index to split.
PassThroughFieldSetMapper just use the default filedSet. you can define your own field mapper.
?
?
Spring batch sample 之 text to DB例子很簡單:
txt文件如下:
sampleSource.txtkinaei,30zoubin,40ZHUTOU,65wufeiran,51
需要存放到一張表中:
? CREATE MEMORY TABLE BATCH_TEST(NAME VARCHAR(20) NOT NULL PRIMARY KEY,AGE BIGINT)
? 利用sts自帶的spring-batch的模板生成樣板代碼。自己完成的無非是reader 和 writer兩塊。
? 下面是主要的配置代碼:
? <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:batch="http://www.springframework.org/schema/batch"xsi:schemaLocation="http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch-2.0.xsdhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"><description>Example job to get you started. It provides askeleton for a typical batch application.</description><job id="job1" xmlns="http://www.springframework.org/schema/batch"><step id="step1" parent="simpleStep"><tasklet><chunk reader="reader" writer="writer"/></tasklet></step></job><!--<bean id="reader" class="org.springframework.sample.batch.example.ExampleItemReader"><property name="sampleFile" value="classpath:sampleSource.txt" /></bean> --><bean id="reader" class="org.springframework.batch.item.file.FlatFileItemReader"><property name="resource" value="classpath:sampleSource.txt" /><property name="lineMapper" ><bean id="defaultLineMapper" class="org.springframework.batch.item.file.mapping.DefaultLineMapper"><property name="lineTokenizer"><bean class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer"><property name="names"><list><value>name</value><value>age</value></list></property></bean></property><property name="fieldSetMapper"><bean class="org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper"><property name="prototypeBeanName" value="testbean" /></bean></property></bean> </property></bean><bean id="testbean" class="org.springframework.sample.batch.example.TestBean" scope="prototype"/><bean id="writer" class="org.springframework.sample.batch.example.ExampleItemWriter" ><property name="dataSource" ref="dataSource" /></bean> <bean id="simpleStep"class="org.springframework.batch.core.step.item.SimpleStepFactoryBean"abstract="true"><property name="transactionManager" ref="transactionManager" /><property name="jobRepository" ref="jobRepository" /><property name="startLimit" value="100" /><property name="commitInterval" value="1" /></bean></beans>?
?
主要的工作就是把需要讀取的文件是一個逗號分割的文件,先把每一行轉換為一個bean然后交給writer去寫入數據庫。
首先來看一下reader,Spring提供的基礎設施及其完善,幾乎不用寫任何代碼就能把一個reader配置完成了。一個reader主要由兩部分組成:
??? 【1】resource 告訴reader從哪里去讀文件
????? <property name="resource" value="classpath:sampleSource.txt" />
【2】lineMapper 就是說txt文件中的每一行映射成怎樣的一個bean。
????? 如何把文件的一行映射成為一個bean呢?
? 【A】需要知道分割符號式什么,在spring 中就叫做:lineTokenizer。可能的話還要提供每個字段對應的名稱。
?????????????? <property name="lineTokenizer"><bean class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer"><property name="names"><list><value>name</value><value>age</value></list></property></bean></property>
?? 這里告訴系統用逗號分隔符,并且第一字段叫name,第二個字段叫age
????????? 【B】需要把txt文件中的字段映射到bean中的對應字段中并且做好字段的類型轉換工作。Spring中就叫做fieldSetMapper
??????????????? <property name="fieldSetMapper"><bean class="org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper"><property name="prototypeBeanName" value="testbean" /></bean></property>
????? 這里用到了spring的基礎設施,即BeanWrapperFieldSetMapper它會根據txt文件讀出的字段與給定的bean進行同名裝配,自動的映射成了一個bean叫做testbean。
【C】 testbean 是什么的 定義如下
??? <bean id="testbean" class="org.springframework.sample.batch.example.TestBean" scope="prototype"/>package org.springframework.sample.batch.example;import java.io.Serializable;public class TestBean implements Serializable{private String name;private Integer age;public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;} }
這樣reader就寫好了。
剩下的就是writer了,由于spring沒有提供方面的Database ItemWriters只能自己寫了。
?? package org.springframework.sample.batch.example;import java.util.List;import javax.sql.DataSource;import org.apache.commons.lang.builder.ToStringBuilder; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.batch.item.ItemWriter; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.TransactionCallback; import org.springframework.transaction.support.TransactionTemplate; import org.springframework.util.StringUtils;/*** Dummy {@link ItemWriter} which only logs data it receives.*/ public class ExampleItemWriter implements ItemWriter<Object> {private static final Log log = LogFactory.getLog(ExampleItemWriter.class);private DataSource dataSource;public DataSource getDataSource() {return dataSource;}public void setDataSource(DataSource dataSource) {this.dataSource = dataSource;}/*** @see ItemWriter#write(Object)*/public void write(List<? extends Object> data) throws Exception {TestBean rs=null;for(Object line : data){rs=(TestBean)line; //actual just one}final Object[] params=new Object[2];params[0]=rs.getName();params[1]=rs.getAge();System.out.println(ToStringBuilder.reflectionToString(rs));TransactionTemplate transactionTemplate = new TransactionTemplate(new DataSourceTransactionManager(dataSource));transactionTemplate.execute(new TransactionCallback() {public Object doInTransaction(TransactionStatus arg0) {JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);jdbcTemplate.update("insert into BATCH_TEST(NAME,AGE) VALUES(?,?)",params);return null;}});}}
??
?? 配置如下:
?? <bean id="writer" class="org.springframework.sample.batch.example.ExampleItemWriter" ><property name="dataSource" ref="dataSource" /></bean>
??
?? 最后談一下總體的感覺:
????? 【1】代碼簡單清晰許多,只需要把精力放在reader和writer的代碼中。其他的如出錯處理等都有spring代勞了。
【2】自動裝配的這個reader用起來非常方便。
【3】自動實現了有狀態的讀取。為了防止讀寫過程中突然出錯,在啟動的時候重復讀,或者漏讀。以前讀文件的時候要么是先把整個文件讀寫完畢后再commit,既浪費應用服務器的內存,又影響db的性能。要么要再寫個文件記錄讀取的條數,重啟后先判斷讀取的位置,在接著做。現在SPRING的這個reader自動提供了(當然代價是建立了記錄狀態的spring_batch的一系列的表),非常方便。
【4】在寫writer的時候有spring來管理connection的事務提交。原來自己寫的時候需要把connection傳來傳去以保證事務的完整性。比如如果要實現讀兩行再一次提交的話,可能connect 會貫穿于reader和writer或者再寫個類去管理這個connection這里都提交給了spring。
實踐下來我的結論是如果你要寫一個讀取文件,再做相應的處理后寫入數據庫的程序的話利用spring-batch絕對物有所值。
- batch2.zip (36.5 KB)
?
總結
以上是生活随笔為你收集整理的spring batch的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Oracle中的UPDATE FROM解
- 下一篇: Spring batch Job def