TA的每日心情 | 开心 2021-12-13 21:45 |
---|
签到天数: 15 天 [LV.4]偶尔看看III
|
quartz负责定时,spring batch负责批量,MyBatis负责持久化数据库,具体每个框架的介绍请参考其它文章,本节主要做spring boot + quartz + spring batch + mybatis的整合。
案例:指定距当前时间5s后,每隔3s时间执行一次批处理任务,批处理任务是读取数据库表记录并打印出来。
数据库采用DB2数据库,库表为users,记录为:
一、建立一个spring boot工程,并在pom.xml中引入依赖jar包
- [code]<?xml version="1.0" encoding="UTF-8"?>
- <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <groupId>com.lzj</groupId>
- <artifactId>demo</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- <packaging>jar</packaging>
- <name>demo</name>
- <description>Demo project for Spring Boot</description>
- <parent>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-parent</artifactId>
- <version>1.5.10.RELEASE</version>
- <relativePath /> <!-- lookup parent from repository -->
- </parent>
- <properties>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
- <java.version>1.8</java.version>
- </properties>
- <dependencies>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context-support</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-batch</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-oxm</artifactId>
- </dependency>
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- </dependency>
- <!-- <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope> </dependency> -->
- <dependency>
- <groupId>mysql</groupId>
- <artifactId>mysql-connector-java</artifactId>
- <scope>runtime</scope>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-test</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.springframework.batch</groupId>
- <artifactId>spring-batch-test</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- </dependency>
- <dependency>
- <groupId>org.quartz-scheduler</groupId>
- <artifactId>quartz</artifactId>
- <version>2.3.0</version>
- </dependency>
- <dependency>
- <groupId>com.h2database</groupId>
- <artifactId>h2</artifactId>
- <scope>runtime</scope>
- </dependency>
- <dependency>
- <groupId>org.mybatis</groupId>
- <artifactId>mybatis</artifactId>
- <version>3.4.6</version>
- </dependency>
- <dependency>
- <groupId>org.mybatis</groupId>
- <artifactId>mybatis-spring</artifactId>
- <version>1.3.2</version>
- </dependency>
- <dependency>
- <groupId>com.alibaba</groupId>
- <artifactId>druid</artifactId>
- <version>1.1.9</version>
- </dependency>
- </dependencies>
- <build>
- <plugins>
- <plugin>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-maven-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
- </project>
复制代码 [/code]
二、配置定时
spring-context-support的jar包作了quartz和spring batch的整合。QuartzJobBean类起连接quartz和spring batch的作用。quartz定时执行QuartzJobBean的继承类,在继承类中去执行启动批量任务,达到定时启动批量的作用。
1、创建QuartzJobBean的继承类
- [code]package com.lzj.quartz;
- import java.text.SimpleDateFormat;
- import java.util.Date;
- import org.h2.util.New;
- import org.quartz.JobDataMap;
- import org.quartz.JobDetail;
- import org.quartz.JobExecutionContext;
- import org.quartz.JobExecutionException;
- import org.quartz.JobKey;
- import org.springframework.batch.core.Job;
- import org.springframework.batch.core.JobExecution;
- import org.springframework.batch.core.JobParameters;
- import org.springframework.batch.core.JobParametersBuilder;
- import org.springframework.batch.core.configuration.JobLocator;
- import org.springframework.batch.core.launch.JobLauncher;
- import org.springframework.scheduling.quartz.QuartzJobBean;
- public class QuartzJobLauncher extends QuartzJobBean {
- /*-------------方式一:获取jobName、jobLauncher和jobLocator*/
- // private String jobName;
- // private JobLauncher jobLauncher;
- // private JobLocator jobLocator;
- //
- // public String getJobName() {
- // return jobName;
- // }
- //
- // public void setJobName(String jobName) {
- // this.jobName = jobName;
- // }
- //
- // public JobLauncher getJobLauncher() {
- // return jobLauncher;
- // }
- //
- // public void setJobLauncher(JobLauncher jobLauncher) {
- // this.jobLauncher = jobLauncher;
- // }
- //
- // public JobLocator getJobLocator() {
- // return jobLocator;
- // }
- //
- // public void setJobLocator(JobLocator jobLocator) {
- // this.jobLocator = jobLocator;
- // }
- /*------------------------方式一获取结束------------------------------*/
- @Override
- protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
- /*-------------方式二:获取jobName、jobLauncher和jobLocator-------------------*/
- JobDetail jobDetail = context.getJobDetail();
- JobDataMap jobDataMap = jobDetail.getJobDataMap();
- String jobName = jobDataMap.getString("jobName");
- JobLauncher jobLauncher = (JobLauncher) jobDataMap.get("jobLauncher");
- JobLocator jobLocator = (JobLocator) jobDataMap.get("jobLocator");
- System.out.println("jobName : " + jobName);
- System.out.println("jobLauncher : " + jobLauncher);
- System.out.println("jobLocator : " + jobLocator);
- /*-----------------------------方式二获取结束---------------------------------*/
- SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
- String date = sf.format(new Date());
- System.out.println("Current Time : " + date);
- try {
- Job job = jobLocator.getJob(jobName);
- /*启动spring batch的批处理作业*/
- JobExecution jobExecution = jobLauncher.run(job, new JobParametersBuilder().addDate("date", new Date()).toJobParameters());
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
复制代码 [/code]
2、配置定时任务
- [code]<?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.xsd">
- <bean id="quartzJob" class="com.lzj.quartz.QuartzJobLauncher"></bean>
- <!-- 注册job -->
- <bean id="jobRegistry" class="org.springframework.batch.core.configuration.support.MapJobRegistry"></bean>
- <bean class="org.springframework.batch.core.configuration.support.JobRegistryBeanPostProcessor">
- <property name="jobRegistry" ref="jobRegistry"></property>
- </bean>
- <!-- jobLauncher在batch-config.xml文件中定义了 -->
- <bean id="jobDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
- <property name="jobClass" value="com.lzj.quartz.QuartzJobLauncher"></property>
- <property name="jobDataMap">
- <map>
- <entry key="jobName" value="myJob"></entry>
- <entry key="jobLauncher" value-ref="jobLauncher"></entry>
- <entry key="jobLocator" value-ref="jobRegistry"></entry>
- </map>
- </property>
- </bean>
- <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
- <property name="jobDetail" ref="jobDetail"></property>
- <property name="cronExpression" value="0/3 * * * * ?"></property>
- <property name="startDelay" value="3000"></property>
- </bean>
- <bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
- <property name="triggers" ref="cronTrigger"></property>
- </bean>
- </beans>
复制代码 [/code]
三、配置spring batch的job作业
1、首先创建batch的作业类,实现Tasklet接口即可
程序中用到的UserDao 与数据库打交道的接口在后面通过mybatis进行定义。
- [code]package com.lzj.springbatch.tasklet;
- import java.util.List;
- import org.springframework.batch.core.StepContribution;
- import org.springframework.batch.core.scope.context.ChunkContext;
- import org.springframework.batch.core.step.tasklet.Tasklet;
- import org.springframework.batch.repeat.RepeatStatus;
- import com.lzj.mybatis.dao.UserDao;
- import com.lzj.springbatch.model.User;
- public class MyTasklet implements Tasklet {
- /*在配置文件batch-confi.xml中定义MyTasklet的bean时,传入UserDao 的属性*/
- private UserDao userDao;
- public UserDao getUserDao() {
- return userDao;
- }
- public void setUserDao(UserDao userDao) {
- this.userDao = userDao;
- }
- @Override
- public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
- User user = new User();
- user.setId(1);
- List<User> users = userDao.select(user);
- for(User user1 : users){
- System.out.println(user1);
- }
- return RepeatStatus.FINISHED;
- }
- }
复制代码 [/code]
2、配置job作业
- [code]<?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" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.3.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
- <!-- <context:property-placeholder location="classpath:db.properties"/> -->
- <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
- <property name="dataSource" ref="dataSource"></property>
- </bean>
- <bean id="jobRepository" class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean">
- <property name="dataSource" ref="dataSource"></property>
- <property name="transactionManager" ref="transactionManager"></property>
- </bean>
- <bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
- <property name="jobRepository" ref="jobRepository"></property>
- </bean>
- <batch:job id="myJob" restartable="true">
- <batch:step id="myStep" allow-start-if-complete="true">
- <batch:tasklet ref="myTasklet">
- </batch:tasklet>
- </batch:step>
- </batch:job>
- <bean id="myTasklet" class="com.lzj.springbatch.tasklet.MyTasklet">
- <!-- <property name="dataSource" ref="dataSource"></property> -->
- <property name="userDao" ref="userDao"></property>
- </bean>
- </beans>
复制代码 [/code]
四、配置mybatis的持久化层
1、在spring boot中整合mybatis的配置
- [code]<?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-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd">
- <bean id="propertyConfigure" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
- <property name="locations">
- <list>
- <value>classpath:db.properties</value>
- </list>
- </property>
- </bean>
- <!--spring batch和mybatis共用一个数据源-->
- <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
- <property name="url" value="${jdbc.jdbcUrl}" />
- <property name="username" value="${jdbc.user}" />
- <property name="password" value="${jdbc.password}" />
- <property name="driverClassName" value="${jdbc.driverClass}" />
- <property name="initialSize" value="3" />
- <property name="minIdle" value="3" />
- <property name="maxActive" value="3" />
- <!-- 配置获取连接等待超时的时间 -->
- <property name="maxWait" value="60000" />
- <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
- <property name="timeBetweenEvictionRunsMillis" value="60000" />
- <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
- <property name="minEvictableIdleTimeMillis" value="300000" />
- <property name="testWhileIdle" value="true" />
- <property name="testOnBorrow" value="false" />
- <property name="testOnReturn" value="false" />
- </bean>
- <!-- 申明式事务 -->
- <tx:annotation-driven transaction-manager="transactionManager" />
- <!--mybatis-config.xml为mybatis的一些属性配置,如无必须要求,可不配置-->
- <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
- <property name="dataSource" ref="dataSource" />
- <property name="configLocation" value="classpath:mybatis-config.xml" />
- <!-- <property name="typeAliasesPackage" value="domain.bean" /> -->
- <property name="mapperLocations">
- <array>
- <value>classpath:mapper/*.xml</value>
- </array>
- </property>
- </bean>
- <!-- 配置加载Dao -->
- <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
- <property name="basePackage" value="com.lzj.mybatis.dao"></property>
- <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
- </bean>
- </beans>
复制代码 [/code]
mybatis-config.xml中只配置了开启mybatis的二级缓存功能
- [code]<?xml version="1.0" encoding="UTF-8" ?>
- <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
- <configuration>
- <settings>
- <setting name="cacheEnabled" value="true" />
- </settings>
- </configuration>
复制代码 [/code]
数据库的properties文件db.properties为:
- [code]jdbc.user=my_name
- jdbc.password=my_password
- jdbc.driverClass=com.ibm.db2.jcc.DB2Driver
- jdbc.jdbcUrl=jdbc:db2:xx.xxx.xx.xxx:50000/database_name
复制代码 [/code]
2、创建mybatis的接口,程序通过接口来操作mybatis与数据库交互
- [code]package com.lzj.mybatis.dao;
- import java.util.List;
- import com.lzj.springbatch.model.User;
- public interface UserDao {
- public List<User> select(User user);
- }
复制代码 [/code]
3、编写mybatis的mapper文件,接口操作mapper文件,
- [code]mapper文件与数据库交互
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
- <mapper namespace="com.lzj.mybatis.dao.UserDao">
- <resultMap type="com.lzj.springbatch.model.User" id="ResultMap">
- <result column="ID" property="id"/>
- <result column="NAME" property="name"/>
- <result column="AGE" property="age"/>
- </resultMap>
- <select id="select" resultMap="ResultMap">
- select * from SQLJ.users
- <where>
- <if test="id != null">ID > #{id}</if>
- </where>
- </select>
- </mapper>
复制代码 [/code]
五、run
测试方法如下:
- [code]@SpringBootApplication
- public class DemoApplication {
- public static void main(String[] args) throws JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException, JobParametersInvalidException {
- Set<Object> set = new HashSet<>();
- set.add("classpath:batch-config.xml");
- set.add("classpath:quartz-config.xml");
- set.add("applicationContext.xml");
- SpringApplication app = new SpringApplication(DemoApplication.class);
- app.setSources(set);
- ApplicationContext context = app.run(args);
- }
- }
复制代码 [/code]
启动测试方法,输出日志如下:
- [code]……
- jobName : myJob
- jobLauncher : org.springframework.batch.core.launch.support.SimpleJobLauncher@4ba309ec
- jobLocator : org.springframework.batch.core.configuration.support.MapJobRegistry@4564eee8
- Current Time : 2018-04-13 19:48:00
- 2018-04-13 19:48:00.032 INFO 4788 --- [eduler_Worker-2] o.s.b.c.l.support.SimpleJobLauncher : Job: [FlowJob: [name=myJob]] launched with the following parameters: [{date=1523620080009}]
- 2018-04-13 19:48:00.090 INFO 4788 --- [eduler_Worker-2] o.s.batch.core.job.SimpleStepHandler : Executing step: [myStep]
- User [id=2, name=huwei, age=28]
- User [id=3, name=lijie, age=26]
- 2018-04-13 19:48:00.140 INFO 4788 --- [eduler_Worker-2] o.s.b.c.l.support.SimpleJobLauncher : Job: [FlowJob: [name=myJob]] completed with the following parameters: [{date=1523620080009}] and the following status: [COMPLETED]
- jobName : myJob
- jobLauncher : org.springframework.batch.core.launch.support.SimpleJobLauncher@4ba309ec
- jobLocator : org.springframework.batch.core.configuration.support.MapJobRegistry@4564eee8
- Current Time : 2018-04-13 19:48:03
- 2018-04-13 19:48:03.017 INFO 4788 --- [eduler_Worker-3] o.s.b.c.l.support.SimpleJobLauncher : Job: [FlowJob: [name=myJob]] launched with the following parameters: [{date=1523620083000}]
- 2018-04-13 19:48:03.057 INFO 4788 --- [eduler_Worker-3] o.s.batch.core.job.SimpleStepHandler : Executing step: [myStep]
- User [id=2, name=huwei, age=28]
- User [id=3, name=lijie, age=26]
- 2018-04-13 19:48:03.089 INFO 4788 --- [eduler_Worker-3] o.s.b.c.l.support.SimpleJobLauncher : Job: [FlowJob: [name=myJob]] completed with the following parameters: [{date=1523620083000}] and the following status: [COMPLETED]
- jobName : myJob
- jobLauncher : org.springframework.batch.core.launch.support.SimpleJobLauncher@4ba309ec
- jobLocator : org.springframework.batch.core.configuration.support.MapJobRegistry@4564eee8
- Current Time : 2018-04-13 19:48:06
- 2018-04-13 19:48:06.019 INFO 4788 --- [eduler_Worker-4] o.s.b.c.l.support.SimpleJobLauncher : Job: [FlowJob: [name=myJob]] launched with the following parameters: [{date=1523620086001}]
- 2018-04-13 19:48:06.058 INFO 4788 --- [eduler_Worker-4] o.s.batch.core.job.SimpleStepHandler : Executing step: [myStep]
- User [id=2, name=huwei, age=28]
- User [id=3, name=lijie, age=26]
- 2018-04-13 19:48:06.094 INFO 4788 --- [eduler_Worker-4] o.s.b.c.l.support.SimpleJobLauncher : Job: [FlowJob: [name=myJob]] completed with the following parameters: [{date=1523620086001}] and the following status: [COMPLETED]
- ……
复制代码 [/code]
通过日志可以看出,每3s执行一次job任务
工程目录为:
|
|