210417:定时任务未生效-Java 正则表达式-解决IDEA提示JAVA字符串常量过长-关于SQL和MySQL的语句执行顺序-not a GROUP BY expression-去重是dis...

一. 定时任务未生效

@Scheduled不生效了:有一天我的定时任务突然不执行了

可能原因 任务是懒加载的,调用一次之后才会加载执行

解决方法:手动配置了 定时任务的 ScheduledThreadPoolExecutor 代码如下:

@Configuration
public class ScheduleConfig implements SchedulingConfigurer {

    @Override
    public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
        scheduledTaskRegistrar.setScheduler(new ScheduledThreadPoolExecutor(Runtime.getRuntime().availableProcessors(),
                                                                            new ThreadFactory() {
                                                                                @Override
                                                                                public Thread newThread(Runnable r) {
                                                                                    return new Thread(r,"my-schedule");
                                                                                }
                                                                            }));
    }
}

基于 @Scheduled 的定时任务,其实会在 bean 实例化阶段 的 BeanPostProcessor(的具体子类实现ScheduledAnnotationBeanPostProcessorpostProcessAfterInitialization)将 所有附带 @Scheduled注解的方法检测出,分析对应的 参数内容, 然后加入各个任务队列之中。

我们配置了 定时任务 使用自己的 ScheduledThreadPoolExecutor 内部其实 基于 DelayQueue,每次任务执行完成之后会计算是否需要下次执行,以及下次执行的时间,然后将任务在放入队列之中。

关于 @EnableScheduling,不加这个注解,在项目启动时 @Scheduled(cron = "0 30 19 * * ?") 这个不会执行, 但是 @Scheduled(fixedDelay = 2)会执行, 因为 initialDelay是默认值的缘故,在将任务加入队列之前会 先 调用一下当前的任务,所以项目启动时 会执行一次。

二. Java 正则表达式:语法讲解和常用表达式汇总

使用正则表达式需要引入 java.util.regex 包,我们就从这里入手讲解:

210417:定时任务未生效-Java 正则表达式-解决IDEA提示JAVA字符串常量过长-关于SQL和MySQL的语句执行顺序-not a GROUP BY expression-去重是dis..._第1张图片

java.util.regex 包主要包括以下三个类:

Pattern 类:

Pattern 对象是一个正则表达式的编译表示。Pattern 类没有公共构造方法。要创建一个 Pattern 对象,你必须首先调用其公共静态编译方法,它返回一个 Pattern 对象。该方法接受一个正则表达式作为它的第一个参数。

Matcher 类

Matcher 对象是对输入字符串进行解释和匹配操作的引擎。与Pattern类一样,Matcher 也没有公共构造方法。你需要调用 Pattern 对象的 matcher 方法来获得一个 Matcher 对象。

210417:定时任务未生效-Java 正则表达式-解决IDEA提示JAVA字符串常量过长-关于SQL和MySQL的语句执行顺序-not a GROUP BY expression-去重是dis..._第2张图片

PatternSyntaxException:

PatternSyntaxException 是一个非强制异常类,它表示一个正则表达式模式中的语法错误。

1. 正则表达式的使用:

/* import java.util.regex.*; */
public void RegexExample() {
    String input = "I am Jimmy from mp.csdn.net";
    String regex = ".*csdn.*";

    // 方式1:String 的 matches 方法
    boolean flag1 = input.matches(regex);

    // 方式2:Pattern 对象的 matches 方法
    boolean flag2 = Pattern.matches(regex, input);

    // 方式3: Matcher 对象的 matches 方法
    Pattern p = Pattern.compile(regex);
    Matcher m = p.matcher(input);
    boolean flag3 = m.matches();

    System.out.println("字符串中是否包含了'csdn'子字符串? " + flag1 );
    System.out.println("字符串中是否包含了'csdn'子字符串? " + flag2 );
    System.out.println("字符串中是否包含了'csdn'子字符串? " + flag3 );
}

输出结果:

  • 字符串中是否包含了'csdn'子字符串? true
  • 字符串中是否包含了'csdn'子字符串? true
  • 字符串中是否包含了'csdn'子字符串? true

从上面的代码中,你会看到一个现象:

  • 3种方式的底层实现其实是一样的,只是封装的成度不一样,实际也确实如此;
  • 明白方式3,更有助于理解正则的执行过程;

2. 正则表达式语法

在其他语言中,\ 表示:我想要在正则表达式中插入一个普通的(字面上的)反斜杠,请不要给它任何特殊的意义。

在 Java 中,\ 表示:我要插入一个正则表达式的反斜线,所以其后的字符具有特殊的意义。

常用表达式汇总

三. 解决IDEA提示JAVA字符串常量过长问题

环境:

Intellij IDEA 2018.1.5;

在做一个非常长的JSON 转对象的dubug时Intellij IDEA 编译不通过,报”java常量字符串太长”,解决方案如下.

IDEA的操作流程:

File -> Settings -> Build,Execution,Deployment -> Compiler -> Java Compiler。

210417:定时任务未生效-Java 正则表达式-解决IDEA提示JAVA字符串常量过长-关于SQL和MySQL的语句执行顺序-not a GROUP BY expression-去重是dis..._第3张图片
210417:定时任务未生效-Java 正则表达式-解决IDEA提示JAVA字符串常量过长-关于SQL和MySQL的语句执行顺序-not a GROUP BY expression-去重是dis..._第4张图片

点击 Use Compiler, 选择Eclipse, 点击确定保存即可。

三. 关于SQL和MySQL的语句执行顺序

1. SQL执行顺序

  1. from
  2. join
  3. on
  4. where
  5. group by(开始使用select中的别名,后面的语句中都可以使用)
  6. avg,sum....
  7. having
  8. select
  9. distinct
  10. order by

从这个顺序中我们不难发现,所有的 查询语句都是从from开始执行的,在执行过程中,每个步骤都会为下一个步骤生成一个虚拟表,这个虚拟表将作为下一个执行步骤的输入。

第一步:首先对from子句中的前两个表执行一个笛卡尔乘积,此时生成虚拟表 vt1(选择相对小的表做基础表)

第二步:接下来便是应用on筛选器,on 中的逻辑表达式将应用到 vt1 中的各个行,筛选出满足on逻辑表达式的行,生成虚拟表 vt2

第三步:如果是outer join 那么这一步就将添加外部行,left outer jion 就把左表在第二步中过滤的添加进来,如果是right outer join 那么就将右表在第二步中过滤掉的行添加进来,这样生成虚拟表 vt3

第四步:如果 from 子句中的表数目多余两个表,那么就将vt3和第三个表连接从而计算笛卡尔乘积,生成虚拟表,该过程就是一个重复1-3的步骤,最终得到一个新的虚拟表 vt3。

第五步:应用where筛选器,对上一步生产的虚拟表引用where筛选器,生成虚拟表vt4,在这有个比较重要的细节不得不说一下,对于包含outer join子句的查询,就有一个让人感到困惑的问题,到底在on筛选器还是用where筛选器指定逻辑表达式呢?on和where的最大区别在于,如果在on应用逻辑表达式那么在第三步outer join中还可以把移除的行再次添加回来,而where的移除的最终的。举个简单的例子,有一个学生表(班级,姓名)和一个成绩表(姓名,成绩),我现在需要返回一个x班级的全体同学的成绩,但是这个班级有几个学生缺考,也就是说在成绩表中没有记录。为了得到我们预期的结果我们就需要在on子句指定学生和成绩表的关系(学生.姓名=成绩.姓名)那么我们是否发现在执行第二步的时候,对于没有参加考试的学生记录就不会出现在vt2中,因为他们被on的逻辑表达式过滤掉了,但是我们用left outer join就可以把左表(学生)中没有参加考试的学生找回来,因为我们想返回的是x班级的所有学生,如果在on中应用学生.班级='x'的话,left outer join会把x班级的所有学生记录找回(感谢网友康钦谋__康钦苗的指正),所以只能在where筛选器中应用学生.班级='x' 因为它的过滤是最终的。

第六步:group by 子句将中的唯一的值组合成为一组,得到虚拟表vt5。如果应用了group by,那么后面的所有步骤都只能得到的vt5的列或者是聚合函数(count、sum、avg等)。原因在于最终的结果集中只为每个组包含一行。这一点请牢记。

第七步:应用cube或者rollup选项,为vt5生成超组,生成vt6.

第八步:应用having筛选器,生成vt7。having筛选器是第一个也是为唯一一个应用到已分组数据的筛选器。

第九步:处理select子句。将vt7中的在select中出现的列筛选出来。生成vt8.

第十步:应用distinct子句,vt8中移除相同的行,生成vt9。事实上如果应用了group by子句那么distinct是多余的,原因同样在于,分组的时候是将列中唯一的值分成一组,同时只为每一组返回一行记录,那么所以的记录都将是不相同的。

第十一步:应用order by子句。按照order_by_condition排序vt9,此时返回的一个游标,而不是虚拟表。sql是基于集合的理论的,集合不会预先对他的行排序,它只是成员的逻辑集合,成员的顺序是无关紧要的。对表进行排序的查询可以返回一个对象,这个对象包含特定的物理顺序的逻辑组织。这个对象就叫游标。正因为返回值是游标,那么使用order by 子句查询不能应用于表表达式。排序是很需要成本的,除非你必须要排序,否则最好不要指定order by,最后,在这一步中是第一个也是唯一一个可以使用select列表中别名的步骤。

第十二步:应用top选项。此时才返回结果给请求者即用户。

2. mysql的执行顺序

SELECT语句定义
一个完成的SELECT语句包含可选的几个子句。SELECT语句的定义如下:
SQL代码