在日常开发中会遇到这样的情景,前端页面编辑了一个数据库中的列表信息,然后将编辑完的列表数据一次性发送到后端,后端将获得的列表数据与数据库中的进行对比然后更新到数据库中。这种情况下每次都要进行重复性的编码工作,为了优化这个情况,本人抽象出了一个工具来处理这种情况。

/**
 * 
 * @param pageList 从页面获取的数据列表
 * @param dbList 从数据库查询获得的数据列表
 * @param compareFunc 函数式接口,第一个参数是数据库的实体对象,第二个参数是页面的实体对象
 * @param merge 函数式接口,第一个参数是页面的实体对象,第二个参数是数据库的实体对象 用来合并页面实体对象的信息到数据库实体对象上
 * @param <T> 实体泛型
 * @return 返回增,删,改的三个列表
 */

import java.util.*;
import java.util.function.BiPredicate;
import java.util.function.BinaryOperator;
import java.util.function.Consumer;

public class UpdateListToDb {
    public static  <T> List<List<T>> compareAndUpdate(List<T> pageList,List<T> dbList, BiPredicate<T,T> compareFunc, BinaryOperator<T> merge) {
        //定义三个列表,分别表示需要在数据库中进行删除的列表deleteList,需要在数据库中进行更新的列表updateList,需要在数据库进行新增的列表insertList
        List<T> deleteList = new ArrayList<>();
        List<T> updateList = new ArrayList<>();
        List<T> insertList = new ArrayList<>();

        //遍历dbList,找出需要删除或更新的对象
        for (T dbObj : dbList) {
            //定义一个标志变量,表示是否在pageList中找到了相同的对象
            boolean found = false;
            //遍历pageList,查找相同的对象
            for (T pageObj : pageList) {
                //使用compareFunc比较两个对象是否相等
                if (compareFunc.test(pageObj, dbObj)) {
                    //如果相等,则说明是同一个对象
                    //将标志变量设为true
                    found = true;
                    //跳出内层循环
                    break;
                }
            }
            //如果没有找到相同的对象,则说明需要删除
            if (!found) {
                //将dbObj添加到deleteList中
                deleteList.add(dbObj);
            }
        }

        //遍历pageList,找出需要新增或更新的对象
        for (T pageObj : pageList) {
            //定义一个标志变量,表示是否在dbList中找到了相同的对象
            boolean found = false;
            //遍历dbList,查找相同的对象
            for (T dbObj : dbList) {
                //使用compareFunc比较两个对象是否相等
                if (compareFunc.test(pageObj, dbObj)) {
                    //如果相等,则说明是同一个对象
                    //将标志变量设为true
                    found = true;
                    //使用update方法更新dbObj的属性为pageObj的属性
                    dbObj = merge.apply(pageObj,dbObj);
                    //将dbObj添加到updateList中
                    if (dbObj!=null){
                        updateList.add(dbObj);
                    }
                    //跳出内层循环
                    break;
                }
            }
            //如果没有找到相同的对象,则说明需要新增
            if (!found) {
                //将pageObj添加到insertList中
                insertList.add(pageObj);
            }
        }

        //返回三个列表组成的列表作为结果
        return Arrays.asList(insertList,deleteList, updateList);
    }

    public static <T> List<List<T>> compareAndUpdateToDb(
            List<T> pageList,
            List<T> dbList,
            BiPredicate<T, T> compareFunc,
            BinaryOperator<T> merge,
            Consumer<List<T>> insertAction,
            Consumer<List<T>> deleteAction,
            Consumer<List<T>> updateAction
    ) {
        //定义三个列表,分别表示需要在数据库中进行删除的列表deleteList,需要在数据库中进行更新的列表updateList,需要在数据库进行新增的列表insertList
        List<T> deleteList = new ArrayList<>();
        List<T> updateList = new ArrayList<>();
        List<T> insertList = new ArrayList<>();

        //遍历dbList,找出需要删除或更新的对象
        for (T dbObj : dbList) {
            //定义一个标志变量,表示是否在pageList中找到了相同的对象
            boolean found = false;
            //遍历pageList,查找相同的对象
            for (T pageObj : pageList) {
                //使用compareFunc比较两个对象是否相等
                if (compareFunc.test(pageObj, dbObj)) {
                    //如果相等,则说明是同一个对象
                    //将标志变量设为true
                    found = true;
                    //跳出内层循环
                    break;
                }
            }
            //如果没有找到相同的对象,则说明需要删除
            if (!found) {
                //将dbObj添加到deleteList中
                deleteList.add(dbObj);
            }
        }

        //遍历pageList,找出需要新增或更新的对象
        for (T pageObj : pageList) {
            //定义一个标志变量,表示是否在dbList中找到了相同的对象
            boolean found = false;
            //遍历dbList,查找相同的对象
            for (T dbObj : dbList) {
                //使用compareFunc比较两个对象是否相等
                if (compareFunc.test(pageObj, dbObj)) {
                    //如果相等,则说明是同一个对象
                    //将标志变量设为true
                    found = true;
                    //使用update方法更新dbObj的属性为pageObj的属性
                    dbObj = merge.apply(pageObj, dbObj);
                    //将dbObj添加到updateList中
                    if (dbObj != null) {
                        updateList.add(dbObj);
                    }
                    //跳出内层循环
                    break;
                }
            }
            //如果没有找到相同的对象,则说明需要新增
            if (!found) {
                //将pageObj添加到insertList中
                insertList.add(pageObj);
            }
        }

        // 若insertAction不为null,则执行数据库插入操作
        if (insertAction != null) {
            insertAction.accept(insertList);
        }
        // 若updateAction不为null,则执行数据库更新操作
        if (updateAction != null) {
            updateAction.accept(updateList);
        }
        // 若deleteAction不为null,则执行数据库删除操作
        if (deleteAction != null) {
            deleteAction.accept(deleteList);
        }

        //返回三个列表组成的列表作为结果
        return Arrays.asList(insertList, deleteList, updateList);
    }

    public static <T> List<List<T>> processUpdateList(
            List<T> updateList,
            BiPredicate<T, T> compareFunc,
            Consumer<List<T>> deleteAction,
            Consumer<List<T>> updateAction
    ) {
        List<T> toBeDeleted = new ArrayList<>();
        List<T> toBeUpdated = new ArrayList<>();
        Set<T> encountered = new HashSet<>();

        for (T currentItem : updateList) {
            boolean isDuplicate = false;

            // 检查当前项目是否已经遇到过
            for (T encounteredItem : encountered) {
                if (compareFunc.test(currentItem, encounteredItem)) {
                    isDuplicate = true;
                    break;
                }
            }

            if (isDuplicate) {
                // 如果这个元素是重复的,则添加到删除列表
                toBeDeleted.add(currentItem);
            } else {
                // 否则,添加到更新列表并标记为已遇到
                toBeUpdated.add(currentItem);
                encountered.add(currentItem);
            }
        }

        if (!toBeDeleted.isEmpty() && deleteAction != null) {
            deleteAction.accept(toBeDeleted);
        }

        if (!toBeUpdated.isEmpty() && updateAction != null) {
            updateAction.accept(toBeUpdated);
        }
        return Arrays.asList(toBeUpdated, toBeDeleted);
    }

}