orcl定時任務小弟是乾乾接觸到,感受很是好用,其在數據批量處理和移植上都很是不錯。java
下面我來講明我使用的定時任務:web
首先我已經構建好了ssh架構,並在spring配置文件中寫好了觸發器spring
<?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:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"> <!-- 啓動觸發器的配置開始 --> <bean name="startupDelay" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <!-- <property value="60" ></property> --> <property name="triggers"> <list> <!-- 每30秒執行一次 --> <!-- <ref bean="meTestDataScheduleJobTrigger" /> --> <!-- 每2分鐘執行一次 --> <!-- <ref bean="insertBusConDataScheduleJobTrigger" /> --> <!-- 向客戶表中插入數據 --> <!-- <ref bean="meRadomDataScheduleJobTrigger" /> --> <!-- 測試抓取APP數據保存到中間表 --> <ref bean="meTakeAppDataScheduleJobTrigger" /> </list> </property> <property name="autoStartup" value="true" /> </bean>
首先該觸發器是隻須要一個,id 只是一個代號,能夠隨便寫, 後面引用的class必定是固定的觸發器類,這個spring都已經給了,sql
若是有多個定時任務,能夠在<property>屬性中定義list屬性, 進行添加。總之觸發器只要一個就能夠了數據庫
<!-- 測試抓取APP數據保存到中間表 --> <bean id="meTakeAppDataScheduleJobTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> <property name="jobDetail"> <ref bean="meTakeAppDataScheduleJobDetail" /> </property> <property name="cronExpression"> <!-- 測試每5分鐘執行一次 --> <!-- <value>0 10 1 * * ?</value> --> <value>0 0/1 * * * ?</value> </property> </bean> <bean id="meTakeAppDataScheduleJob" class="com.minxinloan.auto.schedule.MeTakeCustData" /> <bean id="meTakeAppDataScheduleJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <property name="targetObject"> <ref bean="meTakeAppDataScheduleJob" /> </property> <property name="targetMethod"> <value>toMidData</value> </property> </bean>
而後開始配置觸發器中配置的屬性:meTakeAppDataScheduleJobTrigger,寫一個bean以meTakeAppDataScheduleJobTrigger命名,並制定固定的類,該bean下也有兩個屬性,一個指定了另外一個固定的類,一個是<property name="cronExpression">,這個我只知道寫上,具體意思還不清楚。express
第一個屬性指定了固定的類,還要用bean進行定義<bean id="meTakeAppDataScheduleJobDetail"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">apache
這個bean下的屬性就能夠直接寫你要執行的目標類和目標方法了。只能有一組目標類和目標方法。session
<bean id="meTakeAppDataScheduleJob" class="com.minxinloan.auto.schedule.MeTakeCustData" />這個就是目標類,它裏面要執行的方法就是目標方法
mybatis
接下來開始寫目標類,也就是定時任務要執行的MeTakeCustData類。架構
@Scope("prototype") @Controller public class MeTakeCustData { private final static Logger log = Logger.getLogger(MeTestDataTask.class); private final static SimpleDateFormat sd =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); @Autowired MeTakeCustDataService meTakeAppDataService; @Autowired QuartzJobManagerService quartzJobManagerService; public void toMidData(){ String beginDate =sd.format(System.currentTimeMillis()); try { log.info("抓取App端數據向中間表保存定時任務(start):"+sd.format(System.currentTimeMillis())); meTakeAppDataService.getAppData(); log.info("抓取App端數據向中間表保存定時任務(end):"+sd.format(System.currentTimeMillis())); quartzJobManagerService.updateQuartzjobInfo("meTakeAppDataScheduleJobTrigger", quartzJobManagerService.JOB_STATUS_SUCCESS, "執行成功", beginDate); } catch (Exception e) { log.error("抓取App端數據向中間表保存的數據異常:"+e.getMessage()); // quartzJobManagerService.updateQuartzjobInfo("meTakeAppDataScheduleJobTrigger", quartzJobManagerService.JOB_STATUS_SUCCESS, "執行成功", beginDate); } } }
這個目標類中的toMidData方法就是要執行的方法,在配置文件中都有配置,能夠參看。
該方法中最主要的方法就是 meTakeAppDataService.getAppData();咱們來看一下getAPPData()方法:
@Service(value = "MeTakeAppDataService") @Transactional public class MeTakeCustDataServiceImpl implements MeTakeCustDataService { public final static Logger logger = Logger.getLogger(MeTakeCustDataServiceImpl.class); private final static SimpleDateFormat sd =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); @Resource() @Qualifier("jdbcDao") private JdbcDao jdbcDao; @Resource() @Qualifier("jdbcDao1") private JdbcDao jdbcDao1; @Override public void getAppData() { System.out.println("開始抓取App端客戶信息"); List<Map> list = this.findCusData(); for(int i = 0; i < list.size(); i++){ System.out.println("抓取到的App端客戶信息的id爲:" + list.get(i).get("ID").toString()); String sql = "insert into me_mid_customer_info " + "(id," + "ch_name," + "sex_cd," + "id_type_cd," + "id_number," + "phone_number," + "data_handle_date," + "handle_terrace," + "flag," + "self_code," + "other_code) VALUES " + "(seq_me_mid_customer_info.NEXTVAL,'" + getNull(list.get(i).get("NAME")) + "','" + getNull(list.get(i).get("SEX")) + "','" + getNull(list.get(i).get("IDTYPECD")) + "','" + getNull(list.get(i).get("IDNUMBER")) + "','" + getNull(list.get(i).get("PHONENUMBER")) + "','" + sd.format(System.currentTimeMillis()) + "','" + ""//處理平臺IOS,Android + "','" + "1" + "','" + getNull(list.get(i).get("REFERRALCODE")) + "','" + getNull(list.get(i).get("REFERRALOTHERCODE")) + "')"; String sqlUpdate = "update me_customer_info set flag='2'"; try { jdbcDao1.execute(sql); System.out.println("【SUCC】執行數據插入中間表成功!"); jdbcDao.execute(sqlUpdate); System.out.println("【SUCC】修改數據成功"); } catch (Exception e) { System.out.println("【ERROR】執行數據插入中間表報錯!"); e.printStackTrace(); } } } public List findCusData(){ List<Map> lists = new ArrayList<Map>(); String sql = "select t.id," + "t.name," + "t.id_number," + "t.sex," + "t.id_type_cd," + "t.phone_number," + "t.cus_type," + "t.register_time," + "t.invest_status," + "t.remark_info," + "t.referral_code," + "mr.REFERRALED_ID " + " from me_customer_info t left join me_referrals_info mr on mr.cus_id = t.id " + "where t.flag='1'" + " and t.id_number is not null" + " and t.name is not null"; List l = jdbcDao.queryData(sql); //將l中的值取出命名方便取值 for(int i = 0; i < l.size(); i++){ Map map = new HashMap(); List lt = (List)l.get(i); map.put("ID", getNull(lt.get(0))); map.put("NAME", getNull(lt.get(1))); map.put("IDNUMBER", getNull(lt.get(2))); map.put("SEX", getNull(lt.get(3))); map.put("IDTYPECD", getNull(lt.get(4))); map.put("PHONENUMBER", getNull(lt.get(5))); map.put("CUSTYPE", getNull(lt.get(6))); map.put("REGISTERTIME", getNull(lt.get(7))); map.put("INVESTSTATUS", getNull(lt.get(8))); map.put("REMARKINFO", getNull(lt.get(9))); map.put("REFERRALCODE", getNull(lt.get(10))); map.put("REFERRALOTHERCODE", getNull(lt.get(11))); lists.add(map); } return lists; } private String getNull(Object obj){ if(null != obj){ return obj.toString(); }else if(obj.equals("null")){ return ""; }else{ return ""; } }
getAPPData()方法中主要是將findCusData方法中查詢出來的數據插入到me_mid_customer_info表中,這種方式是實現數據傳遞的一種方式,可是這裏要注意這裏邊用了兩個jdbcDao和jdbcDao1, 應爲這個service中對兩個不一樣的數據庫進行了操做(不一樣用戶),須要兩個事物,因此咱們還要在spring的配置文件中開啓兩個事物(前提是你使用的而是hibernate操做,他支持多事物操做。若是是mybatis只能用一個事物進行操做)
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="configurationClass"> <value>org.hibernate.cfg.AnnotationConfiguration</value> </property> <property name="configLocation"> <value>classpath:/springConfig/hibernate.cfg.xml</value> </property> <property name="hibernateProperties"> <value> hibernate.dialect=${hibernate.dialect} hibernate.show_sql=${hibernate.show_sql} hibernate.format_sql=${format_sql} hibernate.jdbc.batch_size=${hibernate.jdbc.batch_size} </value> </property> </bean> <bean id="sessionFactory1" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource1" /> <property name="configurationClass"> <value>org.hibernate.cfg.AnnotationConfiguration</value> </property> <property name="configLocation"> <value>classpath:/springConfig/hibernate.cfg.xml</value> </property> <property name="hibernateProperties"> <value> hibernate.dialect=${hibernate.dialect} hibernate.show_sql=${hibernate.show_sql} hibernate.format_sql=${format_sql} hibernate.jdbc.batch_size=${hibernate.jdbc.batch_size} </value> </property> </bean> <bean id="transactionManager2" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory1" /> </bean> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <context:annotation-config /> <bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor"> <property name="transactionManager" ref="transactionManager" /> <!-- 配置事務屬性 --> <property name="transactionAttributes"> <props> <prop key="*">PROPAGATION_REQUIRED, -Exception</prop> </props> </property> </bean> <bean id="transactionInterceptor2" class="org.springframework.transaction.interceptor.TransactionInterceptor"> <property name="transactionManager" ref="transactionManager2" /> <!-- 配置事務屬性 --> <property name="transactionAttributes"> <props> <prop key="*">PROPAGATION_REQUIRED, -Exception</prop> </props> </property> </bean> <bean class="com.minxin.base.web.hadler.KoalaHandlerExceptionResolver"> <property name="defaultErrorView" value="error"></property> <!-- 定義須要特殊處理的異常,用類名或徹底路徑名做爲key,異常也頁面做爲值 --> <property name="exceptionMappings"> <props> <prop key="com.minxin.base.web.ValidationException">validationError </prop> </props> </property> </bean> <tx:annotation-driven transaction-manager="transactionManager" /> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${mefc.jdbc.driver}" /> <property name="url" value="${mefc.jdbc.url}" /> <property name="username" value="${mefc.jdbc.username}" /> <property name="password" value="${mefc.jdbc.password}" /> <property name="maxActive" value="100" /> <property name="maxIdle" value="30" /> <property name="maxWait" value="1000" /> <property name="defaultAutoCommit" value="true" /> <property name="removeAbandoned" value="true" /> <property name="removeAbandonedTimeout" value="180" /> </bean> <bean id="dataSource1" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${memid.jdbc.driver}" /> <property name="url" value="${memid.jdbc.url}" /> <property name="username" value="${memid.jdbc.username}" /> <property name="password" value="${memid.jdbc.password}" /> <property name="maxActive" value="100" /> <property name="maxIdle" value="30" /> <property name="maxWait" value="1000" /> <property name="defaultAutoCommit" value="true" /> <property name="removeAbandoned" value="true" /> <property name="removeAbandonedTimeout" value="180" /> </bean> <!-- <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName"> <value>java:comp/env/jdbc/minxinDataSource</value> </property> </bean> --> <aop:aspectj-autoproxy /> <bean id="jdbcDao" class="com.minxinloan.dao.impl.JdbcDaoImpl"> <property name="sessionFactory" ref="sessionFactory"></property> </bean> <bean id="jdbcDao1" class="com.minxinloan.dao.impl.JdbcDaoImpl"> <property name="sessionFactory" ref="sessionFactory1"></property> </bean> <bean id="logAspect" class="com.minxinloan.common.log.LogAspect" /> <aop:config> <aop:pointcut id="pointcut" expression="execution( public * com.minxinloan.*.service..*.*(..)) and !execution( * com.minxinloan.common.log..*(..))" /> <aop:aspect id="loggerAspectToDb" ref="logAspect"> <aop:before pointcut-ref="pointcut" method="before" /> <aop:after-returning pointcut-ref="pointcut" method="afterReturn" /> <aop:around pointcut-ref="pointcut" method="around" /> </aop:aspect> </aop:config> <import resource="me_mid_QuartzJob.xml"/>
如此基本配置完成, 啓動服務後,會在配置文件中添加事物,而後開啓觸發器,找到目標類,執行布標方法,數據開始傳遞。