`
frankensteinlin
  • 浏览: 55145 次
  • 性别: Icon_minigender_1
  • 来自: ShangHai
社区版块
存档分类
最新评论

Spring batch sample 之 text to DB

阅读更多
Spring batch sample 之 text to DB
例子很简单:
txt文件如下:
   sampleSource.txt
     kinaei,30
     zoubin,40
     ZHUTOU,65
     wufeiran,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.xsd
		http://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 a
		skeleton 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绝对物有所值。

1
0
分享到:
评论
6 楼 zhizhuoweichen008 2014-02-12  
怎么下载地址都是打不开的,能不能给个完整的源代码
5 楼 skydazzle 2012-07-03  
我想问一下,如果我是想用spring batch 从数据库里读取大量的数据怎么办 ?
4 楼 gthao 2012-04-23  
怎么下载地址都是打不开的?而且只给出一部分代码。。。
3 楼 windcloud1986 2010-11-26  
包格式不对 1b
2 楼 xiandaoyan 2009-11-27  
哥们儿,你提供的资源格式有问题啊,打不开!!!
1 楼 xiandaoyan 2009-11-25  
哥们讲的很细致,感激不尽,给我的学习带来了很大的帮助!!!

相关推荐

Global site tag (gtag.js) - Google Analytics