1. 程式人生 > 實用技巧 >MySQL中的DML、DDL、DCL到底是什麼呢?

MySQL中的DML、DDL、DCL到底是什麼呢?

這篇文章主要給大家介紹了關於Java學習教程之定時任務全家桶的相關資料,文中通過示例程式碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧!

定時任務應用非常廣泛,Java提供的現有解決方案有很多。

本次主要講schedule、quartz、xxl-job、shedlock等相關的程式碼實踐。

一、SpringBoot使用Schedule

核心程式碼:

 1 @Component
 2 public class ScheduleTask {
 3 
 4  private Logger logger = LoggerFactory.getLogger(ScheduleTask.class
); 5 6 @Scheduled(cron = "0/1 * * * * ? ") 7 public void one() { 8 9 logger.info("one:" + new Date()); 10 } 11 12 @Scheduled(cron = "0/1 * * * * ? ") 13 public void two() { 14 15 logger.info("two:" + new Date()); 16 } 17 18 19 @Scheduled(cron = "0/1 * * * * ? ") 20 public void three() {
21 22 logger.info("three:" + new Date()); 23 } 24 }

執行效果如下:

除此之外還可以這樣實現,核心程式碼:

 1 @PropertySource(value = {
 2  "classpath:task.properties",
 3 }, encoding = "utf-8")
 4 @Component("scheduleTask")
 5 public class ScheduleTask implements SchedulingConfigurer {
 6 
 7 
 8  @Value("${TEST_JOB_TASK_CRON}")
9 private String cron; 10 11 @Override 12 public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) { 13 14 scheduledTaskRegistrar.addTriggerTask(new Runnable() { 15 16 @Override 17 public void run() { 18 System.out.println("執行任務:" + DateUtil.date()); 19 20 21 } 22 23 }, new Trigger() { 24 @Override 25 public Date nextExecutionTime(TriggerContext triggerContext) { 26 return new CronTrigger(cron).nextExecutionTime(triggerContext); 27 } 28 }); 29 } 30 31 public void setCron(String cron) { 32 this.cron = cron; 33 } 34 }

有朋友或許很疑惑,為什麼要寫這麼一大堆,這個與前面的程式碼又有何區別呢?

區別是多執行緒並行。其實多執行緒並行也可以不用這麼寫,只需寫一段核心配置類程式碼即可。

定時任務多執行緒配置類:

1 @Configuration
2 public class ScheduleConfig implements SchedulingConfigurer {
3 
4  public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
5  scheduledTaskRegistrar.setScheduler(Executors.newScheduledThreadPool(5));
6  }
7 }

再次啟動,檢視效果,如下:

由此看出走不同的執行緒執行,不同的執行緒執行的好處是,如果某一個執行緒掛掉後,並不會阻塞導致其它定時任務無法執行。

另外如果要想併發執行,前面的配置可以不要,直接用SpringBoot提供的現成註解即可,核心程式碼如下:

 1 @Component
 2 @EnableAsync
 3 public class ScheduleAsyncTask {
 4 
 5  private Logger logger = LoggerFactory.getLogger(ScheduleAsyncTask.class);
 6 
 7  @Scheduled(cron = "0/1 * * * * ? ")
 8  @Async
 9  public void one() {
10 
11  logger.info("one Async:" + new Date());
12  }
13 
14  @Scheduled(cron = "0/1 * * * * ? ")
15  @Async
16  public void two() {
17 
18  logger.info("two Async:" + new Date());
19  }
20 
21 
22  @Scheduled(cron = "0/1 * * * * ? ")
23  @Async
24  public void three() {
25 
26  logger.info("three Async:" + new Date());
27  }
28 }

除此外,還有基於schedule動態定時任務(所謂動態只不過是指cron表示式放在對應的資料表裡),簡單示例程式碼:

 1 @Configuration
 2 public class DynamicScheduleTask implements SchedulingConfigurer {
 3 
 4  @Autowired
 5  @SuppressWarnings("all")
 6  CronMapper cronMapper;
 7 
 8  @Mapper
 9  public interface CronMapper {
10  @Select("select cron from cron limit 1")
11  public String getCron();
12  }
13 
14  /**
15  * 執行定時任務.
16  */
17  public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
18 
19  taskRegistrar.addTriggerTask(
20   //1.新增任務內容(Runnable)
21   () -> System.out.println("執行動態定時任務: " + LocalDateTime.now().toLocalTime()),
22   //2.設定執行週期(Trigger)
23   triggerContext -> {
24    //2.1 從資料庫獲取執行週期
25    String cron = cronMapper.getCron();
26    //2.2 合法性校驗.
27    if (StringUtils.isEmpty(cron)) {
28    // Omitted Code ..
29    }
30    //2.3 返回執行週期(Date)
31    return new CronTrigger(cron).nextExecutionTime(triggerContext);
32   }
33  );
34  }
35 
36 
37 
38 }

核心配置檔案(application.yml):

1 spring:
2  datasource:
3  url: jdbc:mysql://127.0.0.1:3306/test
4  username: root
5  password: 1234

SQL指令碼:

1 DROP DATABASE IF EXISTS `test`;
2 CREATE DATABASE `test`;
3 USE `test`;
4 DROP TABLE IF EXISTS `cron`;
5 CREATE TABLE `cron` (
6  `cron_id` varchar(30) NOT NULL PRIMARY KEY,
7  `cron` varchar(30) NOT NULL 
8 );
9 INSERT INTO `cron` VALUES ('1', '0/5 * * * * ?');

執行效果如下:

二、SpringBoot使用Quartz

1.Maven依賴

1 2 3 4 5 <!--引入quartz定時框架--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> </dependency>

2.配置檔案

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 spring: quartz: #相關屬性配置 properties: org: quartz: scheduler: instanceName: clusteredScheduler instanceId: AUTO jobStore: class: org.quartz.impl.jdbcjobstore.JobStoreTX driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate tablePrefix: QRTZ_ isClustered: true clusterCheckinInterval: 10000 useProperties: false threadPool: class: org.quartz.simpl.SimpleThreadPool threadCount: 10 threadPriority: 5 threadsInheritContextClassLoaderOfInitializingThread: true #資料庫方式 job-store-type: jdbc #初始化表結構 jdbc: initialize-schema: always datasource: url: jdbc:mysql://127.0.0.1:3306/test username: root password: 1234

3.啟動類

1 2 3 4 5 6 7 8 9 10 @SpringBootApplication @EnableScheduling public class BlogQuartzApplication { public static void main(String[] args) { SpringApplication.run(BlogQuartzApplication.class, args); } }

4.配置類

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 @Configuration public class QuartzConfiguration { // 使用jobDetail包裝job @Bean public JobDetail myCronJobDetail() { return JobBuilder.newJob(CouponTimeOutJob.class).withIdentity("couponTimeOutJob").storeDurably().build(); } // 把jobDetail註冊到Cron表示式的trigger上去 @Bean public Trigger CronJobTrigger() { CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0/1 * * * * ?"); return TriggerBuilder.newTrigger() .forJob(myCronJobDetail()) .withIdentity("CouponTimeOutJobTrigger") .withSchedule(cronScheduleBuilder) .build(); } }

5.定時任務類

1 2 3 4 5 6 public class CouponTimeOutJob extends QuartzJobBean { @Override protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException { System.out.println("定時任務執行"); } }

6.啟動成功不報錯

(1)對應的資料庫會生成定時任務相關的資料表

(2)控制檯不斷輸出定時任務執行日誌

三、SpringBoot使用xxl-job

之前寫過一樣的例子,如今簡化了下。

關於xxl-job使用詳情,可以參考我的這篇文章:

SpringBoot整合Xxl-Job

1.Maven依賴

1 2 3 4 5 <dependency> <groupId>com.xuxueli</groupId> <artifactId>xxl-job-core</artifactId> <version>2.2.0</version> </dependency>

2.配置類

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 @Configuration public class XxlJobConfig { private Logger logger = LoggerFactory.getLogger(XxlJobConfig.class); @Value("${xxl.job.admin.addresses}") private String adminAddresses; @Value("${xxl.job.executor.appname}") private String appName; @Value("${xxl.job.executor.ip}") private String ip; @Value("${xxl.job.executor.port}") private int port; @Value("${xxl.job.accessToken}") private String accessToken; @Value("${xxl.job.executor.logpath}") private String logPath; @Value("${xxl.job.executor.logretentiondays}") private int logRetentionDays; @Bean(initMethod = "start", destroyMethod = "destroy") public XxlJobSpringExecutor xxlJobExecutor() { logger.info(">>>>>>>>>>> xxl-job config init."); XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor(); xxlJobSpringExecutor.setAdminAddresses(adminAddresses); xxlJobSpringExecutor.setAppname(appName); xxlJobSpringExecutor.setIp(ip); xxlJobSpringExecutor.setPort(port); xxlJobSpringExecutor.setAccessToken(accessToken); xxlJobSpringExecutor.setLogPath(logPath); xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays); return xxlJobSpringExecutor; } }

3.配置檔案內容

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 # web port server.port=8081 # no web #spring.main.web-environment=false ### xxl-job admin address list, such as "http://address" or "http://address01,http://address02" xxl.job.admin.addresses=http://127.0.0.1:8080/xxl-job-admin ### xxl-job, access token xxl.job.accessToken= ### xxl-job executor appname xxl.job.executor.appname=blog-job-xxl-job ### xxl-job executor registry-address: default use address to registry , otherwise use ip:port if address is null xxl.job.executor.address= ### xxl-job executor server-info xxl.job.executor.ip= xxl.job.executor.port=8888 ### xxl-job executor log-path xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler ### xxl-job executor log-retention-days xxl.job.executor.logretentiondays=30

4.定時任務類

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 @Component public class XxlJobTaskExample { @XxlJob("blogJobHandler") public ReturnT<String> blogJobHandler(String param) throws Exception { System.out.println("執行"); XxlJobLogger.log("XXL-JOB, Hello World."); for (int i = 0; i < 5; i++) { XxlJobLogger.log("beat at:" + i); TimeUnit.SECONDS.sleep(2); } return ReturnT.SUCCESS; } }

5.執行效果

分別如下所示:

四、SpringBoot使用ShedLock

1.匯入Maven依賴

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <!-- 分散式定時任務鎖 --> <!-- https://mvnrepository.com/artifact/net.javacrumbs.shedlock/shedlock-spring --> <dependency> <groupId>net.javacrumbs.shedlock</groupId> <artifactId>shedlock-spring</artifactId> <version>4.0.4</version> </dependency> <!-- 使用redis做分散式任務 --> <dependency> <groupId>net.javacrumbs.shedlock</groupId> <artifactId>shedlock-provider-redis-spring</artifactId> <version>2.5.0</version> </dependency> <!-- redis元件 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>

2.編寫配置類

1 2 3 4 5 6 7 8 9 10 11 @Configuration @EnableSchedulerLock(defaultLockAtMostFor = "PT30M") public class ShedLockConfig { @Bean public LockProvider lockProvider(RedisTemplate redisTemplate) { return new RedisLockProvider(redisTemplate.getConnectionFactory()); } }

3.編寫具體的定時任務

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @Component public class TaskSchedule { /** * 每分鐘執行一次 * [秒] [分] [小時] [日] [月] [周] [年] */ @Scheduled(cron = "1 * * * * ?") @SchedulerLock(name = "synchronousSchedule") public void SynchronousSchedule() { System.out.println("Start run schedule to synchronous data:" + new Date()); } }

4.編寫啟動類

1 2 3 4 5 6 7 @SpringBootApplication @EnableScheduling public class ShedLockRedisApplication { public static void main(String[] args) { SpringApplication.run(ShedLockRedisApplication.class); } }

5.配置檔案

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 server: tomcat: uri-encoding: UTF-8 max-threads: 1000 min-spare-threads: 30 port: 8083 spring: redis: database: 0 host: localhost port: 6379 password: # 密碼(預設為空) timeout: 6000ms # 連線超時時長(毫秒) jedis: pool: max-active: 1000 # 連線池最大連線數(使用負值表示沒有限制) max-wait: -1ms # 連線池最大阻塞等待時間(使用負值表示沒有限制) max-idle: 10 # 連線池中的最大空閒連線 min-idle: 5 # 連線池中的最小空閒連線

6.測試

我之所以用shedlock是因為確保在叢集環境下各微服務的定時任務只執行一個,而不是全部都執行相同的定時任務。

本次測試效果如下: