欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

在SpringBoot+MyBatis中優(yōu)雅處理多表數(shù)據(jù)清洗的實現(xiàn)步驟

 更新時間:2025年03月06日 11:31:13   作者:好奇的菜鳥  
數(shù)據(jù)清洗是指對數(shù)據(jù)進(jìn)行處理和糾錯,以去除或修復(fù)數(shù)據(jù)集中存在的錯誤、不致、不完整和冗余的數(shù)據(jù),從而使數(shù)據(jù)更加準(zhǔn)確、可靠和有用,本文給大家介紹了在SpringBoot和MyBatis中優(yōu)雅處理多表數(shù)據(jù)清洗的實現(xiàn)步驟,需要的朋友可以參考下

問題背景

在實際業(yè)務(wù)中,我們常會遇到數(shù)據(jù)冗余問題。例如,一個公司表(sys_company)中存在多條相同公司名的記錄,但只有一條有效(del_flag=0),其余需要刪除。刪除前需將關(guān)聯(lián)表(如合同草稿表、發(fā)票表等)的外鍵字段(如purchaser_id)替換為保留記錄的ID。這類問題通常涉及多表、多字段的動態(tài)更新,如何高效且安全地實現(xiàn)?

解決方案

我們將通過以下步驟實現(xiàn):

  1. 配置化驅(qū)動:用配置類聲明需要處理的表和字段,避免硬編碼。
  2. 動態(tài)SQL更新:通過MyBatis XML實現(xiàn)批量更新和刪除。
  3. 事務(wù)一致性:確保所有操作原子化執(zhí)行。

實現(xiàn)步驟

1. 定義實體類

CompanyRetainedInfo:封裝需保留的公司信息

import lombok.Data;

@Data
public class CompanyRetainedInfo {
    private String companyName;   // 公司名稱
    private Long retainedId;      // 需保留的公司ID(del_flag=0的記錄)
    private String retainedName;  // 需保留的公司名稱(與companyName一致)
}

• 作用:映射查詢結(jié)果,傳遞保留記錄的ID和名稱。
• Lombok@Data 自動生成Getter/Setter和toString()方法。

2. 定義配置類

TableConfig:聲明需處理的表和外鍵關(guān)系

public class TableConfig {
    private String tableName;    // 表名(如contract_draft)
    private String idColumn;     // 外鍵ID字段(如purchaser_id)
    private String nameColumn;  // 名稱字段(如purchaser_name,可能為null)

    // 構(gòu)造器 + Getter/Setter
    public TableConfig(String tableName, String idColumn, String nameColumn) {
        this.tableName = tableName;
        this.idColumn = idColumn;
        this.nameColumn = nameColumn;
    }
}

3. 編寫MyBatis Mapper接口

CompanyCleanMapper:定義數(shù)據(jù)操作接口(無注解,純XML映射

@Mapper
public interface CompanyCleanMapper {
    // 查詢需保留的公司信息(del_flag=0)
    List<CompanyRetainedInfo> selectRetainedCompanies();

    // 根據(jù)公司名查詢待刪除的ID列表(del_flag!=0)
    List<Long> selectIdsToDelete(String companyName);

    // 更新關(guān)聯(lián)表的外鍵引用
    void updateForeignKeys(
        @Param("config") TableConfig config,
        @Param("retainedId") Long retainedId,
        @Param("retainedName") String retainedName,
        @Param("ids") List<Long> ids
    );

    // 刪除冗余公司記錄
    void deleteCompanies(@Param("ids") List<Long> ids);
}

4. 實現(xiàn)XML映射文件

CompanyCleanMapper.xml:定義動態(tài)SQL邏輯

<?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.example.mapper.CompanyCleanMapper">

    <!-- 查詢需保留的公司 -->
    <select id="selectRetainedCompanies" resultType="CompanyRetainedInfo">
        SELECT 
            company_name AS companyName, 
            id AS retainedId, 
            company_name AS retainedName
        FROM sys_company
        WHERE del_flag = 0
          AND company_name IN (
            SELECT company_name
            FROM sys_company
            GROUP BY company_name
            HAVING COUNT(*) > 1 AND SUM(del_flag = 0) = 1
          )
    </select>

    <!-- 查詢待刪除的ID列表 -->
    <select id="selectIdsToDelete" resultType="long">
        SELECT id
        FROM sys_company
        WHERE company_name = #{companyName}
          AND del_flag != 0
    </select>

    <!-- 動態(tài)更新外鍵引用 -->
    <update id="updateForeignKeys">
        UPDATE ${config.tableName}
        SET
            <choose>
                <when test="config.nameColumn != null">
                    <!-- 同時更新ID和名稱字段 -->
                    ${config.idColumn} = #{retainedId},
                    ${config.nameColumn} = #{retainedName}
                </when>
                <otherwise>
                    <!-- 僅更新ID字段 -->
                    ${config.idColumn} = #{retainedId}
                </otherwise>
            </choose>
        WHERE
            ${config.idColumn} IN
            <foreach item="id" collection="ids" open="(" separator="," close=")">
                #{id}
            </foreach>
    </update>

    <!-- 批量刪除公司記錄 -->
    <delete id="deleteCompanies">
        DELETE FROM sys_company
        WHERE id IN
        <foreach item="id" collection="ids" open="(" separator="," close=")">
            #{id}
        </foreach>
    </delete>

</mapper>

5. 服務(wù)層實現(xiàn)

CompanyCleanService:配置化驅(qū)動批量處理

@Service
@RequiredArgsConstructor
public class CompanyCleanService {
    private final CompanyCleanMapper companyCleanMapper;

    // 配置需要處理的表和字段
    private static final List<TableConfig> TABLE_CONFIGS = Arrays.asList(
        new TableConfig("contract_draft", "purchaser_id", "purchaser_name"),
        new TableConfig("invoice", "company_id", "company_name")
        // 按需添加其他表...
    );

    @Transactional
    public void cleanDuplicateCompanies() {
        // 1. 查詢所有需保留的公司
        List<CompanyRetainedInfo> retainedCompanies = companyCleanMapper.selectRetainedCompanies();
        
        for (CompanyRetainedInfo info : retainedCompanies) {
            // 2. 查詢待刪除的ID列表
            List<Long> idsToDelete = companyCleanMapper.selectIdsToDelete(info.getCompanyName());
            
            if (!idsToDelete.isEmpty()) {
                // 3. 更新所有關(guān)聯(lián)表的外鍵引用
                TABLE_CONFIGS.forEach(config -> 
                    companyCleanMapper.updateForeignKeys(
                        config, 
                        info.getRetainedId(), 
                        info.getRetainedName(), 
                        idsToDelete
                    )
                );
                
                // 4. 刪除冗余公司記錄
                companyCleanMapper.deleteCompanies(idsToDelete);
            }
        }
    }
}

關(guān)鍵設(shè)計說明

  1. 實體類與數(shù)據(jù)映射
    • CompanyRetainedInfo 通過別名(AS retainedId)直接映射查詢結(jié)果,避免額外轉(zhuǎn)換。
    • companyName 和 retainedName 字段值相同,但保留后者以明確語義。

  2. XML動態(tài)SQL優(yōu)勢
    • <choose>:根據(jù)配置動態(tài)決定是否更新名稱字段。
    • <foreach>:自動展開ID列表為IN (id1, id2...),支持批量操作。
    • ${}占位符:安全引用配置的表名和字段名(非用戶輸入,無注入風(fēng)險)。

  3. 事務(wù)與性能優(yōu)化
    • @Transactional:保證“更新外鍵”和“刪除公司”操作的原子性。
    • 索引建議:對sys_company.company_name和關(guān)聯(lián)表的外鍵字段添加索引。

總結(jié)

通過 實體類封裝、配置化表關(guān)系 和 MyBatis動態(tài)SQL,我們實現(xiàn)了一套可擴展的多表數(shù)據(jù)清洗方案。這種模式的核心在于:

  1. 抽象變化部分:將表和字段的差異收斂到配置類中。
  2. 復(fù)用不變邏輯:批量更新和刪除操作由統(tǒng)一服務(wù)驅(qū)動。
  3. 最小化侵入性:新增表只需修改配置,無需改動核心邏輯。

該方案適用于用戶中心、商品系統(tǒng)等存在外鍵關(guān)聯(lián)的冗余數(shù)據(jù)處理場景,讀者可結(jié)合實際需求調(diào)整配置和SQL邏輯。

以上就是在SpringBoot+MyBatis中優(yōu)雅處理多表數(shù)據(jù)清洗的實現(xiàn)步驟的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot MyBatis多表數(shù)據(jù)清洗的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java服務(wù)限流算法的6種實現(xiàn)

    Java服務(wù)限流算法的6種實現(xiàn)

    服務(wù)限流是指通過控制請求的速率或次數(shù)來達(dá)到保護(hù)服務(wù)的目的,本文主要介紹了Java服務(wù)限流算法的6種實現(xiàn),具有一定的參考價值,感興趣的可以了解一下
    2023-05-05
  • Open?Feign之非SpringCloud方式使用示例

    Open?Feign之非SpringCloud方式使用示例

    這篇文章主要為大家介紹了Open?Feign之非SpringCloud方式使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07
  • spring boot 本地圖片不能加載(圖片路徑)的問題及解決方法

    spring boot 本地圖片不能加載(圖片路徑)的問題及解決方法

    這篇文章主要介紹了spring boot 本地圖片不能加載(圖片路徑)的問題,解決的辦法其實很簡單,只要寫一個配置文件,也就是圖片位置的轉(zhuǎn)化器,原理是虛擬一個在服務(wù)器上的文件夾,與本地圖片的位置進(jìn)行匹配。需要的朋友可以參考下
    2018-04-04
  • MyBatis的緩存解析

    MyBatis的緩存解析

    這篇文章主要介紹了MyBatis的緩存解析,一級緩存是SqlSession級別的,通過同一個SqlSession查詢的數(shù)據(jù)會緩存,下次查詢相同的數(shù)據(jù)就會從緩存中直接獲取,不會從數(shù)據(jù)重新訪問,前提必須是同一個SqlSession對象,并且查詢的數(shù)據(jù)相同,需要的朋友可以參考下
    2023-09-09
  • Java獲取本機IP地址的方法代碼示例(內(nèi)網(wǎng)、公網(wǎng))

    Java獲取本機IP地址的方法代碼示例(內(nèi)網(wǎng)、公網(wǎng))

    在IT領(lǐng)域獲取本機IP地址是一項基礎(chǔ)但重要的任務(wù),特別是在網(wǎng)絡(luò)編程、遠(yuǎn)程協(xié)作和設(shè)備通信中,這篇文章主要給大家介紹了關(guān)于Java獲取本機IP地址的方法(內(nèi)網(wǎng)、公網(wǎng)),需要的朋友可以參考下
    2024-07-07
  • Java 類在 Tomcat 中是如何加載的(過程分析)

    Java 類在 Tomcat 中是如何加載的(過程分析)

    這篇文章主要介紹了Java 類在 Tomcat 中是如何加載的過程分析,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-07-07
  • SpringBoot淺析安全管理之基于數(shù)據(jù)庫認(rèn)證

    SpringBoot淺析安全管理之基于數(shù)據(jù)庫認(rèn)證

    在真實的項目中,用戶的基本信息以及角色等都存儲在數(shù)據(jù)庫中,因此需要從數(shù)據(jù)庫中獲取數(shù)據(jù)進(jìn)行認(rèn)證和授權(quán)
    2022-08-08
  • Java8 接口默認(rèn)方法和靜態(tài)方法

    Java8 接口默認(rèn)方法和靜態(tài)方法

    這篇文章主要介紹了Java8 接口默認(rèn)方法和靜態(tài)方法,在默認(rèn)接口中使用關(guān)鍵字default聲明并提供具體實現(xiàn),而且該方法不需要添加public關(guān)鍵字就可以公開調(diào)用,甚至你可以在其實現(xiàn)類中覆寫,帶著對默認(rèn)接口的方法和小編一起探索下面文章內(nèi)容的靜態(tài)方法吧
    2021-10-10
  • springboot @Controller和@RestController的區(qū)別及應(yīng)用詳解

    springboot @Controller和@RestController的區(qū)別及應(yīng)用詳解

    這篇文章主要介紹了springboot @Controller和@RestController的區(qū)別及應(yīng)用,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • springMVC+jersey實現(xiàn)跨服務(wù)器文件上傳

    springMVC+jersey實現(xiàn)跨服務(wù)器文件上傳

    這篇文章主要介紹了springMVC+jersey實現(xiàn)跨服務(wù)器文件上傳,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-08-08

最新評論