用 Spring AOP 优化 IN 查询

SELECT * FROM device WHERE id IN (1, 2, 3, 4)

拆分为

SELECT * FROM device WHERE id IN (1, 2) SELECT * FROM device WHERE id IN (3, 4)

结合SpringAOP写了一个基于注解优化方案,只需要打上注解就可以提升性能了。实现效果以及具体实现逻辑如下:

@SplitWorkAnnotation(setThreadPool = LIST_DEVICE_EXECUTOR, splitLimit = 20, splitGroupNum = 10)
public listDeviceDetail(Long projectId,@NeedSplitParam List<Long> deviceId){
......
}


使用场景=====
fun(a,b,bigList) = fun(a,b,bigListPart1) + fun(a,b,bigListPart2)

定义AOP注解

需要定义的注解参数:

  • setThreadPool: 线程池,可能阻塞比较大,不要用公共的线程池最好自己定义一个
  • handlerReturnClass: 返回值回调函数,对应不同返回值处理逻辑:可能是合并可能取前十条可能求和
  • splitLimit: 超过多少需要拆分
  • splitGroupNum: 拆分时每组多少个
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SplitWorkAnnotation {

    /**
     * 设置线程池
     *
     * @return {@link ThreadPoolEnum}
     */
    ThreadPoolEnum setThreadPool();

    /**
     * 返回值处理
     *
     * @return {@link Class}<{@link ?} {@link extends} {@link HandleReturn}>
     */
    Class<? extends HandleReturn> handlerReturnClass() default MergeFunction.class;

    /**
     * 超过多少开始拆分 >
     *
     * @return int
     */
    int splitLimit() default 1000;

    /**
     * 拆分后每组多少
     *
     * @return int
     */
    int splitGroupNum() default 100;
}

标记需要拆分参数的注解

加在需要拆分的参数上,只支持一个。因为两两组合情况非常复杂,也一般不符合实际使用情况。

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface NeedSplitParam {

}
 
posted @ 2025-04-07 16:52  KLAPT  阅读(20)  评论(0)    收藏  举报