SSM-Quartz定时器

x33g5p2x  于2021-09-27 转载在 其他  
字(16.3k)|赞(0)|评价(0)|浏览(553)

我们就不搞乱七八糟的了 直接使用最佳方案 Quartz注解版 而一般情况使用Quartz都会搭配着数据库进行使用…

小二上代码 来了客官…

项目结构

需要的Maven

  1. <dependencies>
  2. <!--quartz-->
  3. <dependency>
  4. <groupId>org.quartz-scheduler</groupId>
  5. <artifactId>quartz</artifactId>
  6. <version>2.2.3</version>
  7. </dependency>
  8. <dependency>
  9. <groupId>org.quartz-scheduler</groupId>
  10. <artifactId>quartz-jobs</artifactId>
  11. <version>2.2.3</version>
  12. </dependency>
  13. <!--spring-->
  14. <dependency>
  15. <groupId>org.springframework</groupId>
  16. <artifactId>spring-context</artifactId>
  17. <version>5.2.2.RELEASE</version>
  18. </dependency>
  19. <dependency>
  20. <groupId>org.springframework</groupId>
  21. <artifactId>spring-tx</artifactId>
  22. <version>5.2.5.RELEASE</version>
  23. </dependency>
  24. <dependency>
  25. <groupId>org.mybatis</groupId>
  26. <artifactId>mybatis-spring</artifactId>
  27. <version>1.3.2</version>
  28. </dependency>
  29. <dependency>
  30. <groupId>org.springframework</groupId>
  31. <artifactId>spring-jdbc</artifactId>
  32. <version>5.2.5.RELEASE</version>
  33. </dependency>
  34. <dependency>
  35. <groupId>org.aspectj</groupId>
  36. <artifactId>aspectjweaver</artifactId>
  37. <version>1.9.5</version>
  38. </dependency>
  39. <!--java JDBC-->
  40. <dependency>
  41. <groupId>mysql</groupId>
  42. <artifactId>mysql-connector-java</artifactId>
  43. <version>5.1.47</version>
  44. </dependency>
  45. <dependency>
  46. <groupId>org.mybatis</groupId>
  47. <artifactId>mybatis</artifactId>
  48. <version>3.4.6</version>
  49. </dependency>
  50. <!--java druid 连接-->
  51. <dependency>
  52. <groupId>com.alibaba</groupId>
  53. <artifactId>druid</artifactId>
  54. <version>1.1.12</version>
  55. </dependency>
  56. <dependency>
  57. <groupId>log4j</groupId>
  58. <artifactId>log4j</artifactId>
  59. <version>1.2.17</version>
  60. </dependency>
  61. </dependencies>
  62. <build>
  63. <resources>
  64. <resource>
  65. <directory>src/main/java</directory>
  66. <includes>
  67. <include>**/*.xml</include>
  68. </includes>
  69. <filtering>true</filtering>
  70. </resource>
  71. <resource>
  72. <directory>src/main/resources</directory>
  73. <includes>
  74. <include>**/*.*</include>
  75. </includes>
  76. <filtering>true</filtering>
  77. </resource>
  78. </resources>
  79. </build>
  80. </project>

配置文件和表

druid.properties

  1. driverClassName=com.mysql.jdbc.Driver
  2. url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8&autoReconnect=true&failOverReadOnly=false
  3. name=root
  4. pass=root
  5. # 初始化连接数量
  6. initialSize=5
  7. #最小空闲连接
  8. minIdle=3
  9. # 最大连接数
  10. maxActive=10
  11. # 最大超时时间 3秒
  12. maxWait=3000

log4j.properties

  1. ## 设置Logger输出级别和输出目的地(可以指定多个目的地) ###
  2. ### 一般在开发的时候使用debug,开发完成后使用error ###
  3. ### 他们对应的是输出信息的级别,级别越低信息输出越详细,使用debug级别的时候,info中的信息也能输出,使用info的时候,debug对应的信息显示不出来 ###
  4. ### 日志记录器输出级别:fatal>error>warn>info>debug ###
  5. ### 后面的两个对应下方的两处 一处打印在控制台 另一处打印在日志文件里
  6. log4j.rootLogger=debug,console,logFile
  7. #############################################################################################
  8. ### 把日志信息输出到控制台 ###
  9. log4j.appender.console=org.apache.log4j.ConsoleAppender
  10. ### 信息打印到System.err上,红色 ###
  11. log4j.appender.console.Target=System.out
  12. ### 指定日志在控制台上输出的布局类型 采用指定格式的类型 ###
  13. log4j.appender.console.layout=org.apache.log4j.PatternLayout
  14. ### %r:输出自应用启动到输出该 log信息耗费的毫秒数 %x表示信息输出时左对齐
  15. ### %5p:%p表示输出日志信息优先级,即 DEBUG, INFO, WARN, ERROR, FATAL 中间的5控制最小的宽度为5
  16. ### %F:%L %F:输出日志消息产生时所在的文件名称 %L:输出代码中的行号
  17. ### %l:输出日志事件的发生位置,相当于%C.%M(%F:%L)的组合,包括类目名、发生的线程,以及行数
  18. ### %m:输出代码中指定的消息,产生的日志具体信息 %n:输出一个回车换行符, Windows 平台为"\r\n", Unix 平台为"\n"输出日志信息换行
  19. log4j.appender.console.layout.ConversionPattern= -> (%r ms) - %d{yyyy-M-d HH:mm:ss}%x[%5p](%F:%L) %m%n
  20. #############################################################################################
  21. #############################################################################################
  22. ### 把日志信息输出到文件:logt.log 注意:如果有路径\符号一定要写成\\ 否则会被转义 ###
  23. log4j.appender.logFile=org.apache.log4j.FileAppender
  24. ### 指定日志输出的文件名 ###
  25. log4j.appender.logFile.File=D:\\log.log
  26. ### 指定转换模式 ###
  27. log4j.appender.logFile.layout=org.apache.log4j.PatternLayout
  28. ### 指定日志布局类型 ###
  29. ###log4j.appender.logFile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss}%l %F %p %m%n
  30. ###log4j.appender.logFile.layout.ConversionPattern= -> (%r ms) - %d{yyyy-M-d HH:mm:ss}%x[%5p](%F:%L) %m%n
  31. log4j.appender.logFile.layout.ConversionPattern= -> (%r ms) - %d{yyyy-MM-dd HH:mm:ss}%x[%5p]%l %m%n
  32. #############################################################################################

mybatis-config.xml

  1. <?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">
  2. <configuration>
  3. <!-- 配置日志-->
  4. <settings>
  5. <setting name="logImpl" value="LOG4J"/>
  6. <!-- 懒加载-->
  7. <setting name="lazyLoadingEnabled" value="true"/>
  8. <setting name="aggressiveLazyLoading" value="false"/>
  9. <!-- 开启二级缓存-->
  10. <setting name="cacheEnabled" value= "true" />
  11. </settings>
  12. <!-- 别名-->
  13. <typeAliases>
  14. <package name="cn.quartz.pojo"/>
  15. </typeAliases>
  16. <mappers>
  17. <package name="com.htsa.dao"/>
  18. </mappers>
  19. </configuration>

spring核心配置文件 ApplicationContext.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <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" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation=" http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.0.xsd ">
  3. <!--开启Quartz注解驱动-->
  4. <task:annotation-driven/>
  5. <!--包扫描-->
  6. <context:component-scan base-package="cn.quartz"/>
  7. <!-- 配置数据源 使用外部druid.properties配置文件-->
  8. <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
  9. <property name="location" value="classpath:druid.properties"/>
  10. </bean>
  11. <!-- 连接数据库-->
  12. <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
  13. <!-- 基本属性 url、user、password -->
  14. <property name="driverClassName" value="${driverClassName}"/>
  15. <property name="url" value="${url}" />
  16. <property name="username" value="${name}" />
  17. <property name="password" value="${pass}" />
  18. <!-- 初始化连接数量-->
  19. <property name="initialSize" value="${initialSize}" />
  20. <!-- 最小连接数-->
  21. <property name="minIdle" value="${minIdle}" />
  22. <!-- 最大连接数 -->
  23. <property name="maxActive" value="${maxActive}" />
  24. <!-- 最大超时时间 3秒-->
  25. <property name="maxWait" value="${maxWait}"/>
  26. </bean>
  27. <!-- 配置sqlSessionFactory工厂 有了这个就可以使用Mybatis接口了-->
  28. <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
  29. <property name="dataSource" ref="dataSource"/>
  30. <property name="configLocation" value="classpath:mybatis-config.xml"> </property>
  31. </bean>
  32. <!--获取 sqlSession-->
  33. <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
  34. <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"/>
  35. </bean>
  36. <!-- 配置Dao层下接口 自动生成Mapper实现类 类名为 接口首字母小写 -->
  37. <!-- MapperScannerConfigurer内部会自动调用SqlSessionFactoryBean-->
  38. <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
  39. <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
  40. <property name="basePackage" value="cn.quartz.mapper"/>
  41. </bean>
  42. <!-- (事务管理)transaction manager, use JtaTransactionManager for global tx -->
  43. <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  44. <property name="dataSource" ref="dataSource" />
  45. </bean>
  46. <!-- 配置事务通知属性 -->
  47. <tx:advice id="txAdvice" transaction-manager="transactionManager">
  48. <!-- 定义事务传播属性 -->
  49. <tx:attributes>
  50. <tx:method name="insert*" propagation="REQUIRED" />
  51. <tx:method name="update*" propagation="REQUIRED" />
  52. <tx:method name="edit*" propagation="REQUIRED" />
  53. <tx:method name="save*" propagation="REQUIRED" />
  54. <tx:method name="add*" propagation="REQUIRED" />
  55. <tx:method name="new*" propagation="REQUIRED" />
  56. <tx:method name="set*" propagation="REQUIRED" />
  57. <tx:method name="remove*" propagation="REQUIRED" />
  58. <tx:method name="delete*" propagation="REQUIRED" />
  59. <tx:method name="change*" propagation="REQUIRED" />
  60. <tx:method name="check*" propagation="REQUIRED" />
  61. <tx:method name="get*" propagation="REQUIRED" read-only="true" />
  62. <tx:method name="find*" propagation="REQUIRED" read-only="true" />
  63. <tx:method name="load*" propagation="REQUIRED" read-only="true" />
  64. <tx:method name="*" propagation="REQUIRED" read-only="true" />
  65. </tx:attributes>
  66. </tx:advice>
  67. <!-- 配置事务切面 -->
  68. <aop:config>
  69. <aop:pointcut id="serviceOperation" expression="execution(* cn.quartz.service.*.*(..))" />
  70. <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceOperation" />
  71. </aop:config>
  72. </beans>

表user

  1. /* Navicat Premium Data Transfer Source Server : lllllll Source Server Type : MySQL Source Server Version : 50649 Source Host : localhost:3306 Source Schema : test Target Server Type : MySQL Target Server Version : 50649 File Encoding : 65001 Date: 08/03/2021 13:47:09 */
  2. SET NAMES utf8mb4;
  3. SET FOREIGN_KEY_CHECKS = 0;
  4. -- ----------------------------
  5. -- Table structure for user
  6. -- ----------------------------
  7. DROP TABLE IF EXISTS `user`;
  8. CREATE TABLE `user` (
  9. `id` int(11) NOT NULL AUTO_INCREMENT,
  10. `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  11. `age` int(11) NULL DEFAULT NULL,
  12. `sex` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  13. PRIMARY KEY (`id`) USING BTREE
  14. ) ENGINE = InnoDB AUTO_INCREMENT = 12 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
  15. -- ----------------------------
  16. -- Records of user
  17. -- ----------------------------
  18. INSERT INTO `user` VALUES (1, 'hu', 22, '男');
  19. INSERT INTO `user` VALUES (2, 'an', 23, '女');
  20. INSERT INTO `user` VALUES (3, 'he', 22, '男');
  21. INSERT INTO `user` VALUES (4, 'huan', 21, '男');
  22. INSERT INTO `user` VALUES (11, 'huanmin', 22, '男');
  23. SET FOREIGN_KEY_CHECKS = 1;

job

  1. package cn.quartz.job;
  2. import cn.quartz.pojo.User;
  3. import cn.quartz.service.UserService;
  4. import org.quartz.DisallowConcurrentExecution;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.scheduling.annotation.Scheduled;
  7. import org.springframework.stereotype.Component;
  8. import java.util.Date;
  9. import java.util.List;
  10. @Component
  11. @DisallowConcurrentExecution
  12. public class MyTask {
  13. @Autowired
  14. private UserService userService;
  15. @Scheduled(cron = "0/10 * * * * ?") //每10秒执行一次
  16. public void excTask(){
  17. System.out.println("定时任务执行,执行时间是:"+new Date());
  18. List<User> users = userService.selectAll();
  19. System.out.println("查询数据库user表的全部值是:"+users);
  20. }
  21. }

mapper

  1. package cn.quartz.mapper;
  2. import cn.quartz.pojo.User;
  3. import org.apache.ibatis.annotations.Select;
  4. import java.util.List;
  5. public interface UserMapper {
  6. @Select("select * from user")
  7. List<User> selectAll();
  8. }

pojo

  1. package cn.quartz.pojo;
  2. import java.io.Serializable;
  3. public class User implements Serializable {
  4. private Integer id;
  5. private String name;
  6. private Integer age;
  7. private String sex;
  8. ......get set toString
  9. }

service

UserService

  1. package cn.quartz.service;
  2. import cn.quartz.pojo.User;
  3. import java.util.List;
  4. public interface UserService {
  5. List<User> selectAll();
  6. }

impl/UserServiceImpl

  1. package cn.quartz.service.impl;
  2. import cn.quartz.mapper.UserMapper;
  3. import cn.quartz.pojo.User;
  4. import cn.quartz.service.UserService;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.stereotype.Service;
  7. import java.util.List;
  8. @Service
  9. public class UserServiceImpl implements UserService {
  10. @Autowired
  11. private UserMapper userMapper;
  12. @Override
  13. public List<User> selectAll() {
  14. return userMapper.selectAll();
  15. }
  16. }

测试启动类

  1. package cn.quartz;
  2. import org.springframework.context.support.ClassPathXmlApplicationContext;
  3. public class Test {
  4. public static void main(String[] args) {
  5. new ClassPathXmlApplicationContext("ApplicationContext.xml");
  6. }
  7. }

测试结果这里就不贴上了 大概就是没10秒就从数据库查询一次user表内的全部数据 然后打印在控制台

定时器配合Redis使用

在上面案例的基础上我们增加Redis进行使用

我们来想一个案例就是秒杀商品 全部步骤之一中的商品录入

秒杀查询压力是非常大的,我们可以在秒杀之前把秒杀商品存入到Redis缓存中,页面每次列表查询的时候直接从Redis缓存中取,这样会大大减轻MySQL数据库的压力。我们可以创建一个定时任务工程,每天秒杀的前一天运行并加载MySQL数据库数据到Redis缓存。

项目结构:

图中utils里的工具类就不提供了还有和工具类相关的配置文件

因为Redis在java中使用方式有很多 所以为这里只提供思想

关键代码

  1. package cn.quartz.job;
  2. import cn.quartz.pojo.User;
  3. import cn.quartz.service.UserService;
  4. import cn.quartz.utils.JsonTurnUtils;
  5. import cn.quartz.utils.RedisUtis;
  6. import org.quartz.DisallowConcurrentExecution;
  7. import org.springframework.beans.factory.annotation.Autowired;
  8. import org.springframework.scheduling.annotation.Scheduled;
  9. import org.springframework.stereotype.Component;
  10. import java.text.SimpleDateFormat;
  11. import java.util.Date;
  12. import java.util.List;
  13. @Component
  14. @DisallowConcurrentExecution
  15. public class MyTask {
  16. @Autowired
  17. private UserService userService;
  18. //每天23点59分钟 开始将数据库最新的数据录入到 Redis里
  19. @Scheduled(cron = "0 59 23 * * ?")
  20. public void excTask(){
  21. System.out.println("定时任务执行,执行时间是:"+new Date());
  22. List<User> users = userService.selectAll();
  23. System.out.println("查询数据库user表的全部值是:"+users);
  24. String josn= JsonTurnUtils.objTurnJson(users);
  25. RedisUtis.setStringRedis("userAll",josn);
  26. }
  27. //上面代码的测试版
  28. @Scheduled(cron = "0 0/1 * * * ?") //每一分钟录入一次
  29. public void excTask_test(){
  30. System.out.println("定时任务执行,执行时间是:"+new Date());
  31. List<User> users = userService.selectAll();
  32. System.out.println("查询数据库user表的全部值是:"+users);
  33. String josn= JsonTurnUtils.objTurnJson(users);
  34. RedisUtis.setStringRedis("userAll",josn);
  35. //记录录入的时间
  36. Date dNow = new Date( );
  37. SimpleDateFormat ft = new SimpleDateFormat ("yyyy-MM-dd hh:mm:ss");
  38. RedisUtis.setStringRedis("userAll_date", ft.format(dNow));
  39. System.out.println("数据录入到Redis成功");
  40. }
  41. }

然后我们使用reids进行查询下

  1. @Test
  2. public void getKey(){
  3. String userAll = RedisUtis.getStringRedis("userAll");
  4. System.out.println("数据: "+userAll);
  5. String userAll_date= RedisUtis.getStringRedis("userAll_date");
  6. System.out.println("录入数据的最后时间:"+userAll_date);
  7. }

数据: [{“id”:1,“name”:“hu”,“age”:22,“sex”:“男”},{“id”:2,“name”:“an”,“age”:23,“sex”:“女”},{“id”:3,“name”:“he”,“age”:22,“sex”:“男”},{“id”:4,“name”:“huan”,“age”:21,“sex”:“男”},{“id”:11,“name”:“huanmin”,“age”:22,“sex”:“男”}]
录入数据的最后时间:2021-03-08 04:14:00

小结: 使用Quartz定时器能干的事情太多太多了

比如:

  1. 定时生成报表
  2. 信用卡自动还款
  3. 定时给当年暗恋女神发一封匿名贺卡
  4. 想每隔1小时,备份一下自己的爱情动作片
  5. 订单支付来说,超过一定时间会执行这个job,去判断你是否支付,未支付就会取消此次订单
  6. 银行每天会自动下载流水
  7. 出于安全考虑,长时间没有修改密码会发出警告
  8. 会员到期了,TX提醒你进行充值

根据上面的这些案例 我们可以总结出 ,Quartz就是干自动化的 也就是当条件满足时自动完成一些任务而不依托于主程序

注意: 要预防一件事,就是如果集群系统了,那么定时器如何保证在多个系统中只执行一个呢? ,可以使用redis的分布式锁…
点赞 -收藏-关注-便于以后复习和收到最新内容有其他问题在评论区讨论-或者私信我-收到会在第一时间回复如有侵权,请私信联系我感谢,配合,希望我的努力对你有帮助^_^

相关文章