定時從遠程的數據庫中取數據,而後把取出來的數據插入或更新本地的oracle數據庫的表

最近項目中有一種需求:  大體需求是這樣的 經過給定的  用戶名和密碼 要定時從遠程的數據庫中取數據,而後把取出來的數據插入或更新本地的oracle數據庫的表


項目的結構式struts1   hibernate   spring 

這裏使用spring的定時來處理,本身寫了個項目進行測試,目前項目能夠跑的通,

在測試當中遇到了問題,就是使用 spring 提供的jdbcTemplate進行操做數據,使用的是dbcp數據源,能夠查詢到數據,可是inert update  delete  操做數據時,看起來成功了,可是數據庫中的數據並無變化,

查了不少的資料,偶然發現 有人說  dbcp數據源的事務不是自動提交,因此看不到效果,
改用c3p0數據源以後,的確是好了
後來發如今使用dbcp數據源時  把事務的自動提交功能給關閉了
    <property name="defaultAutoCommit">
            <value>false</value>


定時任務的核心代碼開始
項目的組織結構

            < 1 >java

          < 2 >spring

任務類有1個:JobClass.java 
該類的任務就是從定時從sqlserver中取出數據,而後更新oracle中數據
JobClass.java
package com.sinovatech.news.datatransjob;

import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.JdbcTemplate;

import com.sinovatech.news.model.dto.CmsCyUser;

public class JobClass{

    private JdbcTemplate jdbcTemplate_oracle;
    private JdbcTemplate jdbcTemplate_sqlserver;

    /**
     * 1. 定時操做:定時從sqlserver中取數據,更新數據庫
     * 2. 方法以TX結尾時 使用事務的一個條件 ,
     * spring中的bean要使用下面的配置方法
     * <bean id="jobClass" parent="baseTransactionProxy">
        <property name="target">
            <bean class="com.sinovatech.news.datatransjob.JobClass">
                <property name="jdbcTemplate_oracle">
                      <ref bean="jdbcTemplate_oracle"/>
                </property>
                <property name="jdbcTemplate_sqlserver">
                      <ref bean="jdbcTemplate_sqlserver"/>
                </property>
            </bean>
        </property>
    </bean>
     */
    public void myJobTX() {
        List<CmsCyUser> cmsCyUsers = getData();
        updateTicketInfo(cmsCyUsers);
    }

    /**
     * 更新oracle中CMS_CY_USER表的數據,
     * 使用BatchPreparedStatementSetter進行批處理
     * @param users
     */
    public void updateTicketInfo(List<CmsCyUser> users) {
        if(users==null||users.size()==0){
            return;
        }
        final List<CmsCyUser> cyUsers = users;
         String sql = "update CMS_CY_USER set tickets=? where race_num=?";
        jdbcTemplate_oracle.batchUpdate(sql,
                new BatchPreparedStatementSetter() {
                    public void setValues(PreparedStatement ps, int i)
                            throws SQLException {
                        CmsCyUser user = cyUsers.get(i);
                        ps.setInt(1, user.getTickets().intValue());
                        ps.setString(2, user.getRaceNum());
                    }

                    public int getBatchSize() {
                        return cyUsers.size();
                    }
                });
        resetTickets(users,jdbcTemplate_oracle);
    }

    /**
     * 把沒有race_num對應的tickets數據清零
     * @param users
     * @param jdbcTemplateOracle
     */
    private void resetTickets(List<CmsCyUser> users,JdbcTemplate jdbcTemplateOracle) {
        if(users==null||jdbcTemplateOracle==null){
            return;
        }
        StringBuffer buffer = new StringBuffer();
        buffer.append("(");
        for(int i=0;i<users.size()-1;i++ ){
            buffer.append("'"+users.get(i).getRaceNum()+"',");
        }
        buffer.append("'"+users.get(users.size()-1).getRaceNum()+"')");
        String sql = "update CMS_CY_USER set tickets=0 where race_num not in "+buffer.toString();
        jdbcTemplateOracle.update(sql);
    }


    /**
     * 從sqlserver中取出數據
     * @return
     */
    public List<CmsCyUser> getData() {
        List<CmsCyUser> userList = new ArrayList<CmsCyUser>();
        List list = null;
        String sql = "SELECT race_num,tickets  FROM ticketinfo";
        list = jdbcTemplate_sqlserver.queryForList(sql);
        if (!list.isEmpty() && list != null && list.size() > 0) {
            for (int i = 0; i < list.size(); i++) {
                Object obj = list.get(i);
                String[] ticketInfos = obj.toString().split(",");
                // 由於只有2個值,因此直接使用下標來處理
                String raceNum = ticketInfos[0].replaceAll("\\s*", "");
                // 過濾掉含有中文的非法編號
                if (isContainsChinese(raceNum)) {
                    continue;
                }
                String tickets = ticketInfos[1];
                int b2 = tickets.indexOf('}');
                int b1 = tickets.indexOf('=');
                int a = raceNum.indexOf('=');
                CmsCyUser user = new CmsCyUser();
                raceNum = raceNum.substring(a + 1);
                tickets = tickets.substring(b1 + 1, b2);
                user.setRaceNum(raceNum);
                user.setTickets(Long.parseLong(tickets));
                userList.add(user);
            }
        }
        System.out.println("..successful..");
        return userList;
    }

    /**
     * 判斷字符串中是否含有中文字符
     * @param str
     * @return
     */
    public boolean isContainsChinese(String str) {
        Matcher matcher = Pattern.compile("[\u4e00-\u9fa5]").matcher(str);
        boolean flg = false;
        if (matcher.find()) {
            flg = true;
        }
        return flg;
    }

    public JdbcTemplate getJdbcTemplate_sqlserver() {
        return jdbcTemplate_sqlserver;
    }

    public void setJdbcTemplate_sqlserver(JdbcTemplate jdbcTemplateSqlserver) {
        jdbcTemplate_sqlserver = jdbcTemplateSqlserver;
    }

    public JdbcTemplate getJdbcTemplate_oracle() {
        return jdbcTemplate_oracle;
    }

    public void setJdbcTemplate_oracle(JdbcTemplate jdbcTemplateOracle) {
        jdbcTemplate_oracle = jdbcTemplateOracle;
    }
}

調用任務的類sql

MyJob.java數據庫

package com.sinovatech.news.datatransjob;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;
/**
 * spring 定時任務
 * #####spring 定時任務須要繼承QuartzJobBean 這種方式是最經常使用的!
 * #####同時就實現了抽象方法executeInternal
 * 
 */ 
public class MyJOb extends QuartzJobBean{ 
     
    private JobClass jobClass; 
 
    public void setJobClass(JobClass jobClass) {
        this.jobClass = jobClass;
    }

    /**
     * 調用自定義的任務
     */ 
    @Override 
    protected void executeInternal(JobExecutionContext context) 
            throws JobExecutionException { 
        jobClass.myJobTX();
    } 
} 
View Code

Spring的相關的配置信息apache

applicationContext.xml服務器

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">  
  <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> 
    <property name="locations"> 
      <list> 
        <value>classpath:jdbc.properties</value> 
      </list> 
    </property> 
  </bean>
<!—定義oracle的鏈接 此處使用dbcp數據源-->
  <bean id="dataSource"
        class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close">
        <property name="driverClassName">
            <value>${jdbc.driverClassName}</value>
        </property>
        <property name="url">
            <value>${jdbc.url}</value>
        </property>
        <property name="username">
            <value>${jdbc.username}</value>
        </property>
        <property name="password">
            <value>${jdbc.password}</value>
        </property>
        <property name="maxActive">
            <value>100</value>
        </property>
        <property name="maxIdle">
            <value>3</value>
        </property>
        <property name="maxWait">
            <value>-1</value>
        </property>
<!--  我的認爲此處最後開啓數據源事務自動提交功能-->
        <property name="defaultAutoCommit">
            <value>true</value>
        </property>
    </bean>
<!—定義oracle的SessionFactory-->
<bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="lobHandler">
            <ref bean="oracleLobHandler" />
        </property>
        <property name="dataSource">
            <ref local="dataSource" />
        </property>

        <property name="mappingDirectoryLocations">
            <list>
                <value>classpath:/hbm</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">
                    org.hibernate.dialect.Oracle9iDialect
                </prop>
                <prop key="hibernate.jdbc.batch_size">0</prop>
                
                <prop key="hibernate.format_sql">true</prop>
                <prop key="hibernate.show_sql">true</prop>
             <prop key="hibernate.hbm2ddl.auto">update</prop>
            </props>
        </property>
    </bean>


<!-- ******************************  新增sqlserver的數據源和 sessionFactory的配置     begin  *************************************************-->
    
<!—sqlserver 的鏈接,使用dbcp 數據源-->
<bean id="dataSource_sqlserver"
        class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close">
        <property name="driverClassName">
            <value>${sqlserver.driver}</value>
        </property>
        <property name="url">
            <value>${sqlserver.url}</value>
        </property>
        <property name="username">
            <value>${sqlserver.username}</value>
        </property>
        <property name="password">
            <value>${sqlserver.password}</value>
        </property>
        <property name="maxActive">
            <value>100</value>
        </property>
        <property name="maxIdle">
            <value>3</value>
        </property>
        <property name="maxWait">
            <value>-1</value>
        </property>
<!--  我的認爲此處最後開啓數據源事務自動提交功能-->
        <property name="defaultAutoCommit">
            <value>true</value>
        </property>
    </bean>


<bean id="sessionFactory_sqlserver" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource_sqlserver" />
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</prop>
                <prop key="hibernate.connection.autocommit">true</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">true</prop>
                <prop key="hibernate.hbm2ddl.auto">validate</prop>
            </props>
        </property>
    </bean>
<!-- ******************************  新增sqlserver的數據源和 sessionFactory的配置     end  *************************************************-->
<!—定義事務處理-->
    <bean id="baseTransactionProxy"
        class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
        abstract="true">
        <property name="transactionManager">
            <ref bean="transactionManager" />
        </property>
        <property name="transactionAttributes">
            <props>
                <prop key="*RTX">PROPAGATION_REQUIRED,readOnly</prop>
                <prop key="*TX">PROPAGATION_REQUIRED</prop>
            </props>
        </property>
    </bean>
<!—定義oracle的事務管理 ,該事務處理的bean會被引用-->
    <bean id="transactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory">
            <ref local="sessionFactory" />
        </property>
    </bean>
<!--*********************************** 定時任務相關配置    begin  ***********************************-->
  
  <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"/>
  </bean>
  
  <bean id="jdbcTemplate_oracle" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"/>
  </bean>
  
  <bean id="jdbcTemplate_sqlserver" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource_sqlserver"/>
  </bean>
  
<!-- 把數據寫入oracle,此處使用了事務管理 -->
<bean id="jobClass" parent="baseTransactionProxy">
    <property name="target">
        <bean class="com.sinovatech.news.datatransjob.JobClass">
            <property name="jdbcTemplate_oracle">
                  <ref bean="jdbcTemplate_oracle"/>
            </property>
            <property name="jdbcTemplate_sqlserver">
                  <ref bean="jdbcTemplate_sqlserver"/>
            </property>
        </bean>
    </property>
</bean>

<!-- 基礎的配置   相關類的注入 --> 
<bean class="org.springframework.scheduling.quartz.JobDetailBean" id="MyTimeSpringJob"> 
    <property name="jobClass" value="com.sinovatech.news.datatransjob.MyJOb"/>  <!-- value中配置的是自定義的任務類 --> 
    <property name="jobDataAsMap"><!-- 全部的任務類均可以寫在map中,當定時任務中須要注入別的bean的時候,就能夠在這裏注入,我裏面輸入了一個jobClass類 --> 
        <map> 
            <entry key="jobClass" value-ref="jobClass"/> 
        </map> 
    </property> 
</bean> 
<!-- 相關的時間配置 --> 
<bean class="org.springframework.scheduling.quartz.SimpleTriggerBean" id="MyTimesimpleTriggerBean"> 
    <property name="jobDetail" ref="MyTimeSpringJob"/>   <!-- 給MyTimeSpringJob配置時間信息,name的jobDetail是spring內部須要注入的名字 --> 
     <property name="repeatInterval" value="300000"/>       <!--相隔1000毫秒執行一次 --> 
      <property name="startDelay" value="3000"/>          <!--應用服務器啓動3000毫秒後開始執行任務 --> 
</bean> 
 
<!-- ***啓動定時任務*** --> 
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> 
    <property name="triggers"> 
        <list> 
        <ref bean="MyTimesimpleTriggerBean"/> 
        </list> 
    </property> 
</bean>
<!--*********************************** 定時任務相關配置   end  ***********************************-->
</beans>
View Code

數據庫的配置文件Jdbc.properties(在src下面)session

jdbc.driverClassName=oracle.jdbc.driver.OracleDriver
jdbc.url=jdbc:oracle:thin:@127.0.0.1:1521:orcl
jdbc.username=jxbms
jdbc.password=jxbms

sqlserver.username=sa
sqlserver.password=sqlserver
sqlserver.url=jdbc\:jtds\:sqlserver\://localhost\:1433/J2EE
sqlserver.driver=net.sourceforge.jtds.jdbc.Driver
View Code

定時任務的核心代碼結束oracle

相關文章
相關標籤/搜索