Springboot项目启动时加载数据库数据到内存

问题:   

        项目中有一个文件类型表,通过文件后缀获取文件类型,存放在数据库中。由于文件过多,每次遍历文件获取文件类型都需要查询数据库,且我们没有搭Redis等缓存数据库,所以需要在服务启动的时候将数据数据库加载到内存中。

解决办法:使用的是第二种

1、使用static{}静态块儿

       通过@Component注解在服务启动注入是调用static块儿中的逻辑查询数据库存入内存; 在类上使用@Component注解加载时注入类,然后再static{}静态块儿。

2、使用@PostConstruct注解

        被@PostConstruct修饰的方法会在服务器加载Servlet的时候运行,并且只会被服务器执行一次。PostConstruct在构造函数之后执行,init()方法之前执行。PreDestroy()方法在destroy()方法执行之后执行。

@Component
public class FileTypeDetector {
    /**
     * 日志
     */
    private final static Logger logger = LoggerFactory.getLogger(FileTypeDetector.class);

    @Autowired
    private FileSuffixMappingBiz fileSuffixMappingBiz;

    private static final String UNKNOWN_TYPE = "unkown_type";

    public static List fileSuffixMappings = new ArrayList<>();

    /**
     * @Description:
     *
     * @param
     * @Return: void
     * @Author: xxx
     * @Date: 2019/xx/xx
     */
    @PostConstruct
    public void initFileSuffix() {
        //在服务启动时查询数据库数据存入static形式的list中
        fileSuffixMappings = fileSuffixMappingBiz.selectFileSuffix();
    }

    public static String detect(String fileName) {
        //如果文件名为空,返回无效type
        if (StringUtils.isBlank(fileName)) {
            return UNKNOWN_TYPE;
        }

        //获取后缀
        String fileSuffix = fileName.substring(fileName.lastIndexOf(".") > 0 ? fileName.lastIndexOf(".") : 0);

        if (fileSuffixMappings.stream().anyMatch(item -> fileSuffix.equals(item.getFileSuffix()))) {
            return fileSuffix;
        } else {
            return UNKNOWN_TYPE;
        }
    }

    /**
     * @Description: 根据文件名判断文件是否是已知的类型
     *
     * @param fileName
     * @Return: boolean
     * @Author: xxx
     * @Date: 2019/8/16
     */
    public static boolean isKnownTypeByName(String fileName) {
        final String typeHint = detect(fileName);
        return !typeHint.equals(UNKNOWN_TYPE);
    }

    /**
     * @Description: 根据文件名获取文件的类型
     *
     * @param fileName
     * @Return: boolean
     * @Author: xxx
     * @Date: 2019/8/16
     */
    public static String getFileTypeByFileName(String fileName) {
        String fileType = UNKNOWN_TYPE;
        //如果文件名为空,返回无效type
        if (StringUtils.isBlank(fileName)) {
            return fileType;
        }

        //获取后缀
        String fileSuffix = fileName.substring(fileName.lastIndexOf(".") > 0 ? fileName.lastIndexOf(".") : 0);

        for (FileSuffixMapping fileSuffixMapping : fileSuffixMappings) {
            if (fileSuffix.equalsIgnoreCase(fileSuffixMapping.getFileSuffix())) {
                fileType = fileSuffixMapping.getFileType();
                break;
            }
        }

        return fileType;
    }
}

3、定时同步数据库数据到内存中

        由于可能遇到需要往数据库中加一些文件类型,所以要定时同步数据库数据,这样就不用每次修改了数据库都要重启服务,只需等待5分钟即可。这里用到quartz定时任务。

@Component
public class FileTypeSyncScheduled {
    public static final Logger logger = LoggerFactory.getLogger(FileTypeSyncScheduled.class);

    @Autowired
    private FileTypeDetector fileTypeDetector;

    /**
     * 是否同步数据库开关
     */
    @Value("${file.type.sync.open}")
    private Boolean fileSyncOpen;

    /**
     * @Description: 每5分钟同步数据库数据到内存中
     * 0 0/5 * * * ?
     * @param
     * @Return: void
     * @Author: xxx
     * @Date: 2019/8/16
     */
    @Scheduled(cron = "${file.cron}")
    public void syncFileType() {
        //校验开关
        if (!fileSyncOpen) {
            return;
        }
        logger.info("*****************************  开始从数据库同步文件类型到内存中  *****************************");

        try {
            fileTypeDetector.initFileSuffix();
        } catch (Exception e) {
            logger.error("从数据库同步文件类型到内存中出现异常!", e);
        }
    }
}

 

你可能感兴趣的:(Springboot项目启动时加载数据库数据到内存)