SpringBoot如何统一清理数据

 更新时间:2024年01月30日 09:48:46   作者:大道之简  
这篇文章主要介绍了SpringBoot如何统一清理数据问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

业务背景:

一般时序数据会有保存数据周期,例如三个月或者是半年之久,一般方案是定时任务调用dao层删除数据,不方便统一管理,扩展性也不够好,这里通过并发流线程池实现并行执行删除逻辑。

一、接口定义

package com.boot.skywalk.task;
/**
 * 通用数据清理任务接口
 */
@FunctionalInterface
public interface ICleanData {
    /**
     * 清理数据
     */
    void cleanData();
}

二、业务层模拟Dao层删除逻辑

@Slf4j
@Component
public class ConfigService implements ICleanData {
    @Autowired
    private ConfigDao configDao;
 
    @Override
    public void cleanData() {
        configDao.deleteConfigData(); 
        log.info("ConfigService Clean Success");
    }
}
@Slf4j
@Component
public class StatService implements ICleanData {
    @Autowired
    private StatDao statDao;
 
    @Override
    public void cleanData() {
        statDao.deleteStatData();    
        log.info("StatService Clean Success");
    }
}

三、清理任务

@Slf4j
@Component
public class CleanDataTask {
    /**
     * 并发流定时任务清理过期数据,集群部署时候,分布式任务只在一个节点运行即可,XXL-JOB和Quartz中
     */
    public void clean(){
        // 获取所有需要实现业务清理数据的Bean
        List<ICleanData> dataList =CommonBeanUtils.getBeanList(ICleanData.class);
        Instant start=Instant.now();
        log.info("start clean data");
        // 并发流同时执行业务层数据清理任务
        dataList.parallelStream().forEach(cleanable->{
            // 具体异常在各自实现逻辑中单独捕获
           cleanable.cleanData();
        });
        Instant end=Instant.now();
        long costTime = Duration.between(start, end).getSeconds();
        log.info("finish clean data,cost time={}", costTime);
    }
}

四、测试运行

任务并行执行删除逻辑耗时2秒钟,并发流线程池ForkJoinPool.业务开发只需继承数据清理接口实现各自自己的数据清理逻辑即可,这里可以采用自定义线程池+CountDownLatch来实现,业务线程逻辑更加好控制.

【附录SpringBoot项目时间处理】

建表SQL如下:新增和修改时候自动更新时间

create table user_info (
	id int primary key auto_increment comment '主键ID',
    user_name varchar(50) not null comment '用户名称',
    create_time datetime not null default CURRENT_TIMESTAMP comment '创建时间',
    update_time datetime not null default CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP comment '更新时间'
    ) engine = Innodb default charset = utf8mb4 comment '用户信息表';

新增修改都是自动更新时间. 

基于MyBatis-Plus的方式的三层

Mapper层:

package com.boot.skywalk.mapper;
 
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.boot.skywalk.entity.UserInfo;
 
public interface UserInfoMapper extends BaseMapper<UserInfo> {
}

Xml:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.boot.skywalk.mapper.UserInfoMapper">
 
</mapper>

service

package com.boot.skywalk.service;
 
import com.baomidou.mybatisplus.extension.service.IService;
import com.boot.skywalk.entity.UserInfo;
 
public interface UserInfoService extends IService<UserInfo> {
}

impl

package com.boot.skywalk.service.impl;
 
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.boot.skywalk.entity.UserInfo;
import com.boot.skywalk.mapper.UserInfoMapper;
import com.boot.skywalk.service.UserInfoService;
import org.springframework.stereotype.Service;
 
@Service
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {
}

controller

package com.boot.skywalk.controller;
 
import com.boot.skywalk.entity.UserInfo;
import com.boot.skywalk.service.UserInfoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
 
import java.util.List;
 
@Slf4j
@RestController
public class UserInfoController {
 
    @Autowired
    private UserInfoService userInfoService;
 
    /**
     * 查询全部列表
     * @return
     */
    @RequestMapping("/boot/users")
    public List<UserInfo> getUserInfoList(){
        return userInfoService.list();
    }
}

查询列表返回数据.

时间处理策略:

、前段处理展示.

、SimpleDateFormat格式化或者是DateTimeFormatter格式化来增加字段处理,大型项目有专门的TimeUtil来转换各种时间,项目中的时间是point来存储时间戳然后进行转化.

package com.boot.skywalk.entity;
 
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
 
import javax.persistence.Table;
import java.util.Date;
 
@Data
@Table(name="user_info")
public class UserInfo {
    @TableId(type = IdType.AUTO)
    private Integer id;
 
    @TableField("user_name")
    private String userName;
 
    @TableField("create_time")
    @JsonIgnore// 输出结果时隐藏此字段
    private Date createTime;
 
    @TableField("update_time")
    @JsonIgnore// 输出结果时隐藏此字段
    private Date updateTime;
 
    // 时间格式化后的字段,数据库不存在的字段
    @TableField(exist = false)
    private String ctime;
 
    // 时间格式化后的字段,数据库不存在的字段
    @TableField(exist = false)
    private String utime;
}

controller修改.

package com.boot.skywalk.controller;
 
import com.boot.skywalk.entity.UserInfo;
import com.boot.skywalk.service.UserInfoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
 
import java.text.SimpleDateFormat;
import java.util.List;
 
@Slf4j
@RestController
public class UserInfoController {
 
    // 定义时间格式化对象和定义格式化样式
    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 
    @Autowired
    private UserInfoService userInfoService;
 
    /**
     * 查询全部列表
     * @return
     */
    @RequestMapping("/boot/users")
    public List<UserInfo> getUserInfoList(){
        List<UserInfo> list = userInfoService.list();
        list.forEach(user->{
           user.setCtime(dateFormat.format(user.getCreateTime()));
           user.setUtime(dateFormat.format(user.getUpdateTime()));
        });
        return list;
    }
}

、使用@JsonFormat添加对应注解即可

    @TableField("update_time")
    //@JsonIgnore// 输出结果时隐藏此字段
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
    private Date updateTime;

、或者在全局配置文件中进行配置

附录定时任务创建分表】也可以基于并发流创建然后配置完整的告警管理,实现统一接口然后并发流创建.

Xml

<mapper namespace="com.boot.skywalk.mapper.SupportMapper">
    <update id="createTable" parameterType="String">
        create table ${tableName}  (
            id int(11) auto_increment primary key,
            user_name varchar(20) not null,
            user_password varchar(20) not null
        );
    </update>
</mapper>
package com.boot.skywalk.mapper;
 
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
 
@Repository
public interface SupportMapper {
    /**
     * createTable
     * @param tableName
     * @return int
     */
    int createTable(@Param("tableName") String tableName);
}

控制台执行日志: 

information_schema.TABLE表中查看

验证数据库字符串处理时间

数据库建表字段 为timestamp/datatime,前段时间为字符串处理

{
  "name": "Dubbo",
  "address": "GuangZhou",
  "create_time": "2023-01-14 20:19:24"
}
create table result(
  id int(11) auto_increment primary key,
  `name` varchar(10) not null,
  address varchar(30) not null,
  create_time timestamp
);

接口层时间获取json数据,@RequestBody接收,比较简单.

    @PostMapping("/insert/resultVo")
    public String saveResultVo(@RequestBody CustomResultVo customResultVo){
        try {
            resultMapper.save(customResultVo);
        } catch (Exception e) {
            log.info("save error",e);
        }
        return "Success";
    }

这里测试使用jdbcType的DATE类型 

    <!--数据 -->
    <insert id="save" useGeneratedKeys="true" keyProperty="id" parameterType="com.boot.skywalk.vo.CustomResultVo">
        insert into result(`name`,`address`,`create_time`) values(#{name,jdbcType=VARCHAR},#{address,jdbcType=VARCHAR},#{createTime,jdbcType=DATE})
    </insert>

使用Java的Date接收前端时间json字符串参数 

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
 
import java.util.Date;
 
@Data
@NoArgsConstructor
@AllArgsConstructor
public class CustomResultVo {
    private int id;
    private String name;
    private String address;
    /**
     * 设置时间格式,
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
    @JsonProperty("create_time")
    private Date createTime;
}

 MyBatis的JdbcType枚举,这里转换使用TimeStamp

数据库建表语句

查询数据库,发现只有年月日

XML中修改为TimeStamp

再次查询数据,保存正常。

MyBatis处理MySQL字段类型date与datetime

五、总结归纳 

不仅仅是数据清理,也包括一些需要并行的逻辑可以采用并发流的方式来执行,注意是IO密集型还是CPU密集型选择对应的框架和线程池即可.

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 详解Java的Struts框架中栈值和OGNL的使用

    详解Java的Struts框架中栈值和OGNL的使用

    这篇文章主要介绍了Java的Struts框架中栈值和OGNL的使用,Struts框架是Java的SSH三大web开发框架之一,需要的朋友可以参考下
    2015-11-11
  • java.lang.Long cannot be cast to java.lang.Integer数据类型转换异常解决办法

    java.lang.Long cannot be cast to ja

    本文主要介绍了java.lang.Long cannot be cast to java.lang.Integer数据类型转换异常解决办法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07
  • application作用域实现用户登录挤掉之前登录用户代码

    application作用域实现用户登录挤掉之前登录用户代码

    这篇文章主要介绍了application作用域实现用户登录挤掉之前登录用户代码,具有一定参考价值,需要的朋友可以了解下。
    2017-11-11
  • SpringBoot对接小程序微信支付的实现

    SpringBoot对接小程序微信支付的实现

    本文主要介绍了SpringBoot对接小程序微信支付的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧<BR>
    2023-09-09
  • java 获取字节码文件的几种方法总结

    java 获取字节码文件的几种方法总结

    这篇文章主要介绍了java 获取字节码文件的几种方法总结的相关资料,这里总结了三种方法帮助大家实现该功能,需要的朋友可以参考下
    2017-08-08
  • 1秒实现Springboot 图片添加水印功能

    1秒实现Springboot 图片添加水印功能

    这篇文章主要介绍了1秒实现Springboot 图片添加水印功能,本文结合示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-12-12
  • SpringCloud中使用Sentinel实现限流的实战

    SpringCloud中使用Sentinel实现限流的实战

    限流在很多地方都可以使用的到,本篇博客将介绍如何使用SpringCloud中使用Sentinel实现限流,从而达到服务降级的目的,感兴趣的可以了解一下
    2022-01-01
  • Java虚拟机JVM性能优化(一):JVM知识总结

    Java虚拟机JVM性能优化(一):JVM知识总结

    这篇文章主要介绍了Java虚拟机JVM性能优化(一):JVM知识总结,本文是系列文章的第一篇,后续篇章请继续关注脚本之家,需要的朋友可以参考下
    2014-09-09
  • Java实现一键获取Mysql所有表字段设计和建表语句的工具类

    Java实现一键获取Mysql所有表字段设计和建表语句的工具类

    这篇文章主要为大家详细介绍了如何利用Java编写一个工具类,可以实现一键获取Mysql所有表字段设计和建表语句,感兴趣的小伙伴可以了解一下
    2023-05-05
  • Mac下设置Java默认版本的方法

    Mac下设置Java默认版本的方法

    今天工作的时候发现了一个错误,提示java版本太低,无法启动!想起自己装过高版本的Java,但是却没有默认启动,从网上找了一些资料,整理下现在分享给大家,有需要的可以参考借鉴。
    2016-10-10

最新评论