优化SQL之通过构造函数将数据库参数存入单例bean的成员属性中

背景:

        前段时间遇到一个问题,一个定时任务扫描全表的数据,发送一条消息到消息队列中进行消费,三十多万的数据两台机器,二十个线程大概要消费五个多小时,经过排查发现有一条业务SQL执行的特别慢,大概要500ms,关联了四个表查询,其中查询两个表只是为了获取一个固定的菜单id,所以要优化。提高消费速率

思路:

        主要针对SQL进行优化,其他方便也可能存在优化空间,但是不过多分析了,将固定菜单的id提前查询出来,放到bean的成员属性中,这样SQL查询时带上这个id只需要关联两个表查询就行了,但是这个id不可以写死在程序当中,因为不同环境这个菜单的id是不同的,所以需要spring初始化这个bean时候,从数据库查询出这个id,然后注入到这个bean的成员属性中去。

实现代码:

@Service
@Slf4j
public class UserServiceImp implements UserService {
    private static final String userName ="李狗蛋";

    private BsUserPOMapper bsUserPOMapper;
    private  final Integer userId;//李狗蛋

    public UserServiceImp(BsUserPOMapper bsUserPOMapper) {
        this.bsUserPOMapper = bsUserPOMapper;
        this.userId = bsUserPOMapper.selectByUserName(userName).getUserId();
        System.out.println(" init success userId="+this.userId);
    }


    @Override
    public BsUserPO qryUser() {
        return  bsUserPOMapper.selectByPrimaryKey(userId);
    }
}

原理分析:

        使用@service注解将UserServiceImp这个类交由spring ioc来控制它的生命周期,在这个类中定义三个成员属性,一个固定的常量,一个dao层的mapper,一个被final修饰的userId,然后再自定义它的构造函数,用来给这个类的这些成员属性赋初始化的值,构造函数的局部变量是bsUserPOMapper它也是spring注入进来的bean,不用考虑它注入的先后顺序,容器启动时会将他创建出来,这块直接注入使用就可以,再构造方法中将userId赋值为从数据库中查询李狗蛋的id,然后这类的其他方法需要使用这个id的时候,因为是单例bean,直接获取使用就行。

结果:

        原来需要5个多小时才能处理完,优化后只需要20多分种就可以执行完,原来这个SQL需要500ms才响应完,优化后处理完一条业务才使用260ms左右,可以见优化是成功的。

概念:

        什么是构造函数?

        构造函数是用来给对象创建时初始化成员属性的方法,它的方法名和类名相同。spring中ioc会使用反射来创建对象,默认调用对象的无参构造器来创建对象并初始化对象的成员属性,此时的成员属性都是对应类型的默认值,类里面可以不写无参构造器,spring在创建对象的时候会自己帮你加上类的无参构造器并调用,当类中有你自定义的有参构造器时,spring就不会帮你加午餐构造器了,这个时候你想要通过调用这个类的无参构造器来创建对象,它会报错。

思考:

        为什么使用final修饰id?

        因为使用final修饰的变量只允许被赋值一次,你在初始化对id进行赋值,其他调用者就不可以在使用过程中对这个id进行修改了,保证了这个id的唯一性。

猜你喜欢

转载自blog.csdn.net/guliudeng/article/details/126318651