1. data-source-context.xmljava
- <?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:context="http://www.springframework.org/schema/context"
- xmlns:tx="http://www.springframework.org/schema/tx"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
- http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
- http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
-
-
- <context:component-scan base-package="net.etongbao.vasp.ac" />
-
-
-
- <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
- destroy-method="close" abstract="false" scope="singleton">
-
- <property name="driverClass" value="oracle.jdbc.OracleDriver" />
- <property name="jdbcUrl" value="jdbc:oracle:thin:@192.168.1.23:1521:orcl01" />
- <property name="user" value="USR_DEV01" />
- <property name="password" value="2AF0829C" />
- <property name="checkoutTimeout" value="30000" />
- <property name="maxIdleTime" value="120" />
- <property name="maxPoolSize" value="100" />
- <property name="minPoolSize" value="2" />
- <property name="initialPoolSize" value="2" />
- <property name="maxStatements" value="0" />
- <property name="maxStatementsPerConnection" value="0" />
- <property name="idleConnectionTestPeriod" value="30" />
- </bean>
- <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
- <property name="dataSource" ref="dataSource" />
- </bean>
-
- <bean id="transactionManager"
- class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
- <property name="dataSource" ref="dataSource" />
- </bean>
-
- <tx:annotation-driven transaction-manager="transactionManager" />
- </beans>
2. quartz-context.xml commit-interval="10000"每次批量數據的條數,數值越大效率越高,可在此處添加事物處理,spring
每次回滾數就是commit-interval數sql
- <?xml version="1.0" encoding="UTF-8"?>
- <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" xmlns:context="http://www.springframework.org/schema/context"
- xmlns:tx="http://www.springframework.org/schema/tx"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
- http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch-2.1.xsd
- http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
- http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
-
- <import resource="data-source-context.xml"/>
-
-
- <bean id="jobRepository"
- class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean">
- <property name="transactionManager" ref="transactionManager" />
- </bean>
-
-
- <bean id="jobLauncher"
- class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
- <property name="jobRepository" ref="jobRepository" />
- </bean>
-
-
- <batch:job id="ledgerJob">
- <batch:listeners>
- <batch:listener ref="appJobExecutionListener" />
- </batch:listeners>
- <batch:step id="step1">
- <span style="white-space: pre;"> </span> <batch:tasklet transaction-manager="transactionManager">
- <batch:tasklet>
- <batch:listeners>
- <batch:listener ref="itemFailureLoggerListener" />
- </batch:listeners>
- <batch:chunk reader="ledgerReader" writer="ledgerWriter"
- commit-interval="10000" />
- </batch:tasklet>
- </batch:tasklet>
- </batch:step>
- </batch:job>
-
- <bean id="ledgerReader"
- class="org.springframework.batch.item.database.JdbcCursorItemReader">
- <property name="dataSource" ref="dataSource" />
- <property name="sql" value="select * from ledger" />
- <property name="rowMapper" ref="ledgerRowMapper" />
- </bean>
-
- <!-- Spring Batch Job同一個job instance,成功執行後是不容許從新執行的【失敗後是否容許重跑,可經過配置Job的restartable參數來控制,默認是true】,若是須要從新執行,能夠變通處理,
- 添加一個JobParameters構建類,以當前時間做爲參數,保證其餘參數相同的狀況下倒是不一樣的job instance -->
- <bean id="jobParameterBulider" class="org.springframework.batch.core.JobParametersBuilder" />
-
- <bean id="ledgerJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
- <property name="targetObject">
-
- <ref bean="quartzLedgerJob" />
- </property>
- <property name="targetMethod">
-
- <value>execute</value>
- </property>
- </bean>
-
- <bean id="ledgerCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean" >
-
- <property name="jobDetail" >
- <ref bean="ledgerJobDetail" />
- </property>
-
-
- <property name="cronExpression" >
-
- <value>0 45 10 * * ? * </value>
- </property>
-
- </bean>
-
- <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
-
- <property name="triggers">
- <list>
-
- <ref local="ledgerCronTrigger" />
- </list>
- </property>
- </bean>
- lt;/beans>
3.定時調度job類 QuartzLedgerJob.java數據庫
package net.etongbao.vasp.ac.quartz;express
- import java.util.Date;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.batch.core.Job;
- import org.springframework.batch.core.JobParametersBuilder;
- import org.springframework.batch.core.launch.JobLauncher;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Component;
- import org.springframework.util.StopWatch;
-
-
- @Component("quartzLedgerJob")
- public class QuartzLedgerJob {
-
- private static final Logger LOG = LoggerFactory.getLogger(QuartzLedgerJob.class);
-
- @Autowired
- private JobLauncher jobLauncher;
-
- @Autowired
- private Job ledgerJob;
-
- @Autowired
- JobParametersBuilder jobParameterBulider;
-
- private static long counter = 0l;
-
-
- public void execute() throws Exception {
- LOG.debug("start...");
- StopWatch sw = new StopWatch();
- sw.start();
-
- jobParameterBulider.addDate("date", new Date());
- jobLauncher.run(ledgerJob, jobParameterBulider.toJobParameters());
- sw.stop();
- LOG.debug("Time elapsed:{},Execute quartz ledgerJob:{}", sw.prettyPrint(), ++counter);
- }
- }
4.程序啓動類 StartQuartz.javaapi
package net.etongbao.vasp.ac.quartz;tomcat
- import java.io.FileNotFoundException;
-
- import org.springframework.context.support.ClassPathXmlApplicationContext;
-
- public class StartQuartz {
-
- public static void main(String[] args) throws FileNotFoundException {
-
- new ClassPathXmlApplicationContext("/net/etongbao/vasp/ac/resources/quartz-context.xml");
- }
- }
5.pojo類 Ledger.javaoracle
6. LedgerDaoImpl.javaapp
package net.etongbao.vasp.ac.dao.impl;eclipse
- import java.sql.PreparedStatement;
- import java.sql.SQLException;
- import net.etongbao.vasp.ac.dao.LedgerDao;
- import net.etongbao.vasp.ac.pojo.Ledger;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.jdbc.core.JdbcTemplate;
- import org.springframework.jdbc.core.PreparedStatementSetter;
- import org.springframework.stereotype.Repository;
-
-
- @Repository
- public class LedgerDaoImpl implements LedgerDao {
-
- private static final String SAVE_SQL = "insert into ledger_temp (rcv_dt, mbr_nm, chk_nbr, chk_dt, pymt_typ, dpst_amt, pymt_amt, comments) values(?,?,?,?,?,?,?,?)";
-
- @Autowired
- private JdbcTemplate jdbcTemplate;
-
- @Override
- public void save(final Ledger item) {
- jdbcTemplate.update(SAVE_SQL, new PreparedStatementSetter() {
- public void setValues(PreparedStatement stmt) throws SQLException {
- stmt.setDate(1, new java.sql.Date(item.getReceiptDate().getTime()));
- stmt.setString(2, item.getMemberName());
- stmt.setString(3, item.getCheckNumber());
- stmt.setDate(4, new java.sql.Date(item.getCheckDate().getTime()));
- stmt.setString(5, item.getPaymentType());
- stmt.setDouble(6, item.getDepositAmount());
- stmt.setDouble(7, item.getPaymentAmount());
- stmt.setString(8, item.getComments());
- }
- });
- }
-
- }
7.接口 LedgerDao .java
- package net.etongbao.vasp.ac.dao;
-
- import net.etongbao.vasp.ac.pojo.Ledger;
-
- public interface LedgerDao {
- public void save(final Ledger item) ;
- }
8. JdbcTemplete 須要的LedgerRowMapper.java
package net.etongbao.vasp.ac.batch.writer;
- import java.sql.ResultSet;
- import java.sql.SQLException;
-
- import net.etongbao.vasp.ac.pojo.Ledger;
-
- import org.springframework.jdbc.core.RowMapper;
- import org.springframework.stereotype.Component;
-
- @Component("ledgerRowMapper")
- public class LedgerRowMapper implements RowMapper {
- public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
- Ledger ledger = new Ledger();
- ledger.setId(rs.getInt("id"));
- ledger.setReceiptDate(rs.getDate("rcv_dt"));
- ledger.setMemberName(rs.getString("mbr_nm"));
- ledger.setCheckNumber(rs.getString("chk_nbr"));
- ledger.setCheckDate(rs.getDate("chk_dt"));
- ledger.setPaymentType(rs.getString("pymt_typ"));
- ledger.setDepositAmount(rs.getDouble("dpst_amt"));
- ledger.setPaymentAmount(rs.getDouble("pymt_amt"));
- ledger.setComments(rs.getString("comments"));
- return ledger;
- }
- }
9.關鍵類LedgerWriter.java ,寫入數據,負責數據的添加
- package net.etongbao.vasp.ac.batch.writer;
-
- import java.util.List;
-
- import net.etongbao.vasp.ac.dao.LedgerDao;
- import net.etongbao.vasp.ac.pojo.Ledger;
-
- import org.springframework.batch.item.ItemWriter;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Component;
-
- @Component("ledgerWriter")
- public class LedgerWriter implements ItemWriter<Ledger> {
-
- @Autowired
- private LedgerDao ledgerDao;
-
-
- public void write(List<? extends Ledger> ledgers) throws Exception {
- for (Ledger ledger : ledgers) {
- ledgerDao.save(ledger);
- }
- }
-
- }
classPath:
<?xml version="1.0" encoding="UTF-8"?>
- <classpath>
- <classpathentry kind="src" path="src"/>
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jrockit-jdk1.6.0_24-R28.1.3-4.0.1"/>
- <classpathentry kind="lib" path="lib/aopalliance-1.0.jar"/>
- <classpathentry kind="lib" path="lib/c3p0-0.9.1.2.jar"/>
- <classpathentry kind="lib" path="lib/commons-collections-3.2.1.jar"/>
- <classpathentry kind="lib" path="lib/commons-lang-2.3.jar"/>
- <classpathentry kind="lib" path="lib/commons-logging-1.1.1.jar"/>
- <classpathentry kind="lib" path="lib/etb-log4j-1.2.16.jar"/>
- <classpathentry kind="lib" path="lib/etb-slf4j-api-1.5.8.jar"/>
- <classpathentry kind="lib" path="lib/etb-slf4j-log4j12-1.5.8.jar"/>
- <classpathentry kind="lib" path="lib/ojdbc6.jar"/>
- <classpathentry kind="lib" path="lib/org.springframework.aop-3.0.5.RELEASE.jar"/>
- <classpathentry kind="lib" path="lib/org.springframework.asm-3.0.5.RELEASE.jar"/>
- <classpathentry kind="lib" path="lib/org.springframework.aspects-3.0.5.RELEASE.jar"/>
- <classpathentry kind="lib" path="lib/org.springframework.beans-3.0.5.RELEASE.jar"/>
- <classpathentry kind="lib" path="lib/org.springframework.context-3.0.5.RELEASE.jar"/>
- <classpathentry kind="lib" path="lib/org.springframework.context.support-3.0.5.RELEASE.jar"/>
- <classpathentry kind="lib" path="lib/org.springframework.core-3.0.5.RELEASE.jar"/>
- <classpathentry kind="lib" path="lib/org.springframework.expression-3.0.5.RELEASE.jar"/>
- <classpathentry kind="lib" path="lib/org.springframework.instrument-3.0.5.RELEASE.jar"/>
- <classpathentry kind="lib" path="lib/org.springframework.instrument.tomcat-3.0.5.RELEASE.jar"/>
- <classpathentry kind="lib" path="lib/org.springframework.jdbc-3.0.5.RELEASE.jar"/>
- <classpathentry kind="lib" path="lib/org.springframework.jms-3.0.5.RELEASE.jar"/>
- <classpathentry kind="lib" path="lib/org.springframework.orm-3.0.5.RELEASE.jar"/>
- <classpathentry kind="lib" path="lib/org.springframework.oxm-3.0.5.RELEASE.jar"/>
- <classpathentry kind="lib" path="lib/org.springframework.test-3.0.5.RELEASE.jar"/>
- <classpathentry kind="lib" path="lib/org.springframework.transaction-3.0.5.RELEASE.jar"/>
- <classpathentry kind="lib" path="lib/quartz-all-1.6.5.jar"/>
- <classpathentry kind="lib" path="lib/spring-batch-core-2.1.6.RELEASE.jar"/>
- <classpathentry kind="lib" path="lib/spring-batch-infrastructure-2.1.6.RELEASE.jar"/>
- <classpathentry kind="lib" path="lib/spring-batch-test-2.1.6.RELEASE.jar"/>
- <classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
- <classpathentry kind="output" path="bin"/>
- </classpath>
總結: 測試數據8萬多條,響應時間3分多鐘。
關鍵在於quartz-context.xml 中<bean id="ledgerReader"
class="org.springframework.batch.item.database.JdbcCursorItemReader">
<property name="dataSource" ref="dataSource" />
<property name="sql" value="select * from ledger" />
<property name="rowMapper" ref="ledgerRowMapper" />
</bean> 負責讀取數據 ,在程序執行時一次性抓取所有數據後在批量的交給LedgerWriter進行寫操做。固然也可使用分頁讀取JdbcPagingItemReader,但要分頁數量與寫入數量要大寫相同,還能夠對分頁出來的數據進行添加悲觀鎖
LedgerWriter.java 負責寫入數據,每次寫入1000條。