最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot如何統(tǒng)一清理數(shù)據(jù)

 更新時(shí)間:2024年01月30日 09:48:46   作者:大道之簡(jiǎn)  
這篇文章主要介紹了SpringBoot如何統(tǒng)一清理數(shù)據(jù)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

業(yè)務(wù)背景:

一般時(shí)序數(shù)據(jù)會(huì)有保存數(shù)據(jù)周期,例如三個(gè)月或者是半年之久,一般方案是定時(shí)任務(wù)調(diào)用dao層刪除數(shù)據(jù),不方便統(tǒng)一管理,擴(kuò)展性也不夠好,這里通過(guò)并發(fā)流線程池實(shí)現(xiàn)并行執(zhí)行刪除邏輯。

一、接口定義

package com.boot.skywalk.task;
/**
 * 通用數(shù)據(jù)清理任務(wù)接口
 */
@FunctionalInterface
public interface ICleanData {
    /**
     * 清理數(shù)據(jù)
     */
    void cleanData();
}

二、業(yè)務(wù)層模擬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");
    }
}

三、清理任務(wù)

@Slf4j
@Component
public class CleanDataTask {
    /**
     * 并發(fā)流定時(shí)任務(wù)清理過(guò)期數(shù)據(jù),集群部署時(shí)候,分布式任務(wù)只在一個(gè)節(jié)點(diǎn)運(yùn)行即可,XXL-JOB和Quartz中
     */
    public void clean(){
        // 獲取所有需要實(shí)現(xiàn)業(yè)務(wù)清理數(shù)據(jù)的Bean
        List<ICleanData> dataList =CommonBeanUtils.getBeanList(ICleanData.class);
        Instant start=Instant.now();
        log.info("start clean data");
        // 并發(fā)流同時(shí)執(zhí)行業(yè)務(wù)層數(shù)據(jù)清理任務(wù)
        dataList.parallelStream().forEach(cleanable->{
            // 具體異常在各自實(shí)現(xiàn)邏輯中單獨(dú)捕獲
           cleanable.cleanData();
        });
        Instant end=Instant.now();
        long costTime = Duration.between(start, end).getSeconds();
        log.info("finish clean data,cost time={}", costTime);
    }
}

四、測(cè)試運(yùn)行

任務(wù)并行執(zhí)行刪除邏輯耗時(shí)2秒鐘,并發(fā)流線程池ForkJoinPool.業(yè)務(wù)開發(fā)只需繼承數(shù)據(jù)清理接口實(shí)現(xiàn)各自自己的數(shù)據(jù)清理邏輯即可,這里可以采用自定義線程池+CountDownLatch來(lái)實(shí)現(xiàn),業(yè)務(wù)線程邏輯更加好控制.

【附錄SpringBoot項(xiàng)目時(shí)間處理】

建表SQL如下:新增和修改時(shí)候自動(dòng)更新時(shí)間

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)建時(shí)間',
    update_time datetime not null default CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP comment '更新時(shí)間'
    ) engine = Innodb default charset = utf8mb4 comment '用戶信息表';

新增修改都是自動(dòng)更新時(shí)間. 

基于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;
 
    /**
     * 查詢?nèi)苛斜?
     * @return
     */
    @RequestMapping("/boot/users")
    public List<UserInfo> getUserInfoList(){
        return userInfoService.list();
    }
}

查詢列表返回?cái)?shù)據(jù).

時(shí)間處理策略:

、前段處理展示.

、SimpleDateFormat格式化或者是DateTimeFormatter格式化來(lái)增加字段處理,大型項(xiàng)目有專門的TimeUtil來(lái)轉(zhuǎn)換各種時(shí)間,項(xiàng)目中的時(shí)間是point來(lái)存儲(chǔ)時(shí)間戳然后進(jìn)行轉(zhuǎn)化.

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// 輸出結(jié)果時(shí)隱藏此字段
    private Date createTime;
 
    @TableField("update_time")
    @JsonIgnore// 輸出結(jié)果時(shí)隱藏此字段
    private Date updateTime;
 
    // 時(shí)間格式化后的字段,數(shù)據(jù)庫(kù)不存在的字段
    @TableField(exist = false)
    private String ctime;
 
    // 時(shí)間格式化后的字段,數(shù)據(jù)庫(kù)不存在的字段
    @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 {
 
    // 定義時(shí)間格式化對(duì)象和定義格式化樣式
    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 
    @Autowired
    private UserInfoService userInfoService;
 
    /**
     * 查詢?nèi)苛斜?
     * @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添加對(duì)應(yīng)注解即可

    @TableField("update_time")
    //@JsonIgnore// 輸出結(jié)果時(shí)隱藏此字段
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
    private Date updateTime;

、或者在全局配置文件中進(jìn)行配置

附錄定時(shí)任務(wù)創(chuàng)建分表】也可以基于并發(fā)流創(chuàng)建然后配置完整的告警管理,實(shí)現(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);
}

控制臺(tái)執(zhí)行日志: 

information_schema.TABLE表中查看

驗(yàn)證數(shù)據(jù)庫(kù)字符串處理時(shí)間

數(shù)據(jù)庫(kù)建表字段 為timestamp/datatime,前段時(shí)間為字符串處理

{
  "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
);

接口層時(shí)間獲取json數(shù)據(jù),@RequestBody接收,比較簡(jiǎn)單.

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

這里測(cè)試使用jdbcType的DATE類型 

    <!--數(shù)據(jù) -->
    <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接收前端時(shí)間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;
    /**
     * 設(shè)置時(shí)間格式,
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
    @JsonProperty("create_time")
    private Date createTime;
}

 MyBatis的JdbcType枚舉,這里轉(zhuǎn)換使用TimeStamp

數(shù)據(jù)庫(kù)建表語(yǔ)句

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

XML中修改為TimeStamp

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

MyBatis處理MySQL字段類型date與datetime

五、總結(jié)歸納 

不僅僅是數(shù)據(jù)清理,也包括一些需要并行的邏輯可以采用并發(fā)流的方式來(lái)執(zhí)行,注意是IO密集型還是CPU密集型選擇對(duì)應(yīng)的框架和線程池即可.

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Springboot+mybatis plus找不到mapper.xml的問(wèn)題解決

    Springboot+mybatis plus找不到mapper.xml的問(wèn)題解決

    本文主要介紹了Springboot+mybatis plus找不到mapper.xml的問(wèn)題解決,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05
  • 關(guān)于MyBatis Plus中使用or和and問(wèn)題

    關(guān)于MyBatis Plus中使用or和and問(wèn)題

    這篇文章主要介紹了關(guān)于MyBatis Plus中使用or和and問(wèn)題,需要的朋友可以參考下
    2020-12-12
  • Java中Getter和Setter方法及主要區(qū)別

    Java中Getter和Setter方法及主要區(qū)別

    這篇文章主要給大家介紹了關(guān)于Java中Getter和Setter方法及主要區(qū)別的相關(guān)資料,getter和setter方法是用于封裝類中的私有屬性的方法,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-04-04
  • java拋出異常與finally實(shí)例解析

    java拋出異常與finally實(shí)例解析

    這篇文章主要介紹了java拋出異常與finally實(shí)例解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-10-10
  • Java靜態(tài)泛型使用方法實(shí)例解析

    Java靜態(tài)泛型使用方法實(shí)例解析

    這篇文章主要介紹了Java靜態(tài)泛型使用方法實(shí)例解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-06-06
  • 淺談java多線程wait,notify

    淺談java多線程wait,notify

    這篇文章主要介紹了java多線程wait,notify,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,下面小編和大家一起來(lái)學(xué)習(xí)一下吧
    2019-05-05
  • java如何寫接口給別人調(diào)用的示例代碼

    java如何寫接口給別人調(diào)用的示例代碼

    這篇文章主要介紹了java如何寫接口給別人調(diào)用的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • MyBatis一對(duì)一級(jí)聯(lián)更新問(wèn)題小結(jié)

    MyBatis一對(duì)一級(jí)聯(lián)更新問(wèn)題小結(jié)

    日常工作中經(jīng)常會(huì)涉及到一對(duì)一級(jí)聯(lián)更新的問(wèn)題,本文主要介紹了MyBatis一對(duì)一級(jí)聯(lián)更新問(wèn)題小結(jié),具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-01-01
  • Java詳細(xì)分析sleep和wait方法有哪些區(qū)別

    Java詳細(xì)分析sleep和wait方法有哪些區(qū)別

    這篇文章主要介紹了Java中wait與sleep的講解(wait有參及無(wú)參區(qū)別),通過(guò)代碼介紹了wait()?與wait(?long?timeout?)?區(qū)別,wait(0)?與?sleep(0)區(qū)別,需要的朋友可以參考下
    2022-04-04
  • 學(xué)習(xí)Java之如何正確地向上轉(zhuǎn)型與向下轉(zhuǎn)型

    學(xué)習(xí)Java之如何正確地向上轉(zhuǎn)型與向下轉(zhuǎn)型

    面向?qū)ο蟮牡谌齻€(gè)特征是多態(tài),實(shí)現(xiàn)多態(tài)有三個(gè)必要條件:繼承、方法重寫和向上轉(zhuǎn)型,在學(xué)習(xí)多態(tài)之前,我們還要先學(xué)習(xí)Java的類型轉(zhuǎn)換,本篇文章就來(lái)帶大家認(rèn)識(shí)什么是類型轉(zhuǎn)換,看看類型轉(zhuǎn)換都有哪幾種情況,以及如何避免類型轉(zhuǎn)換時(shí)出現(xiàn)異常
    2023-05-05

最新評(píng)論

北辰区| 黔西县| 滨州市| 平果县| 静安区| 尤溪县| 运城市| 灯塔市| 德令哈市| 贵南县| 大竹县| 沂南县| 山东省| 扶风县| 津市市| 廊坊市| 大田县| 文昌市| 文昌市| 石泉县| 双流县| 牟定县| 杭锦旗| 揭阳市| 广水市| 安庆市| 孙吴县| 银川市| 平遥县| 常州市| 平乐县| 永平县| 卢湾区| 吉木萨尔县| 高雄市| 云林县| 邹城市| 河津市| 南康市| 襄樊市| 桦南县|