SpringBoot如何統(tǒng)一清理數(shù)據
業(yè)務背景:
一般時序數(shù)據會有保存數(shù)據周期,例如三個月或者是半年之久,一般方案是定時任務調用dao層刪除數(shù)據,不方便統(tǒng)一管理,擴展性也不夠好,這里通過并發(fā)流線程池實現(xiàn)并行執(zhí)行刪除邏輯。
一、接口定義
package com.boot.skywalk.task;
/**
* 通用數(shù)據清理任務接口
*/
@FunctionalInterface
public interface ICleanData {
/**
* 清理數(shù)據
*/
void cleanData();
}二、業(yè)務層模擬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 {
/**
* 并發(fā)流定時任務清理過期數(shù)據,集群部署時候,分布式任務只在一個節(jié)點運行即可,XXL-JOB和Quartz中
*/
public void clean(){
// 獲取所有需要實現(xiàn)業(yè)務清理數(shù)據的Bean
List<ICleanData> dataList =CommonBeanUtils.getBeanList(ICleanData.class);
Instant start=Instant.now();
log.info("start clean data");
// 并發(fā)流同時執(zhí)行業(yè)務層數(shù)據清理任務
dataList.parallelStream().forEach(cleanable->{
// 具體異常在各自實現(xiàn)邏輯中單獨捕獲
cleanable.cleanData();
});
Instant end=Instant.now();
long costTime = Duration.between(start, end).getSeconds();
log.info("finish clean data,cost time={}", costTime);
}
}四、測試運行

任務并行執(zhí)行刪除邏輯耗時2秒鐘,并發(fā)流線程池ForkJoinPool.業(yè)務開發(fā)只需繼承數(shù)據清理接口實現(xiàn)各自自己的數(shù)據清理邏輯即可,這里可以采用自定義線程池+CountDownLatch來實現(xiàn),業(yè)務線程邏輯更加好控制.
【附錄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 '創(chuàng)建時間',
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();
}
}查詢列表返回數(shù)據.

時間處理策略:
①、前段處理展示.
②、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;
// 時間格式化后的字段,數(shù)據庫不存在的字段
@TableField(exist = false)
private String ctime;
// 時間格式化后的字段,數(shù)據庫不存在的字段
@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;④、或者在全局配置文件中進行配置
【附錄定時任務創(chuàng)建分表】也可以基于并發(fā)流創(chuàng)建然后配置完整的告警管理,實現(xiàn)統(tǒng)一接口然后并發(fā)流創(chuàng)建.
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);
}控制臺執(zhí)行日志:

information_schema.TABLE表中查看

【驗證數(shù)據庫字符串處理時間】
數(shù)據庫建表字段 為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數(shù)據,@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類型
<!--數(shù)據 -->
<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字符串參數(shù)
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

數(shù)據庫建表語句


查詢數(shù)據庫,發(fā)現(xiàn)只有年月日

XML中修改為TimeStamp

再次查詢數(shù)據,保存正常。

MyBatis處理MySQL字段類型date與datetime
五、總結歸納
不僅僅是數(shù)據清理,也包括一些需要并行的邏輯可以采用并發(fā)流的方式來執(zhí)行,注意是IO密集型還是CPU密集型選擇對應的框架和線程池即可.
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
Springboot+mybatis plus找不到mapper.xml的問題解決
本文主要介紹了Springboot+mybatis plus找不到mapper.xml的問題解決,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2023-05-05

