【Java】批量操作优化

批量获取

开发中,有时候难免需要用到类似findAll()方法,或者说获取表中所有数据。但是当这个量很大时,一次性从数据库中加载到内存中,明显不理智。这时候可以采用批量取的方式,比如batchSize为500。

    /**
     * 批量获取任务,删除任务
     */
    private void cleanTask() {

        List<String> projectIds = getAllProjectIds();

        if (isNotEmpty(projectIds)) {

            int skip = 0;

            List<TaskVO> res = null;

            do {
                res = taskService.findAll(skip, batchSize);

                if (res == null || res.isEmpty()) {
                    break;
                }

                deleteBatchTask(projectIds, res);

                skip = skip + batchSize;

            } while (res.size() == batchSize);
        }
    }

批量删除

在执行删除操作时,通常我们会foreach遍历着删,但是遍历一次就是与数据库的一次交互。更常见地,每一次删除时,还会有很多相关的级联删除操作,这样更加拉低了页面的相应。有几个地方可以优化:比如采用线程池来执行整个的批量删除操作;比如可以先做假删除,在夜深人静时采用定时任务来删除;再比如,采用批量删除,也就是in语句。这里主要说的也是第三种,但是如果采用in进行批量删除,也需要注意,不能过分信任in的批量,如果数据量过大,一次性in上万条,数据库也扛不住,此时就可以对in再进行批量。

// 批量删除任务
Functional.batchExec(taskIds, delIds -> taskDAO.deleteTaskTrue(delIds), batchSize);    
    /**
     * 批量删除(真删除)
     *
     * @param taskIds 任务ids
     */
    public void deleteTaskTrue(List<String> taskIds) {
        createDelete().where().in("_id", taskIds).delete();
    }
public class Functional {
    /**
     * 将集合按指定分批大小进行分批操作
     *
     * @param src
     * @param function
     * @param batchSize
     * @param <K>
     */
    public static <K> void batchExec(List<K> src, Consumer<List<K>> function, int batchSize) {

        if (src == null || src.isEmpty()) {
            return;
        }

        if (batchSize <= 0) {
            batchSize = 1;
        }

        int loopTimes;

        if (src.size() % batchSize == 0) {
            loopTimes = src.size() / batchSize;
        } else {
            loopTimes = src.size() / batchSize + 1;
        }

        for (int i = 0; i < loopTimes; i++) {

            List<K> subList;

            if (i == src.size() / batchSize) {
                subList = src.subList(i * batchSize, src.size());
            } else {
                subList = src.subList(i * batchSize, (i + 1) * batchSize);
            }

            function.accept(subList);
        }
    }

    /**
     * 正序排序
     *
     * @param src
     * @param field
     */
    public static void ascSort(List src, String field) {
        sort(src, field, 1);
    }

    /**
     * 逆序排序
     *
     * @param src
     * @param field
     */
    public static void descSort(List src, String field) {
        sort(src, field, -1);
    }

    private static void sort(List src, String field, int direction) {

        if (ValidateUtil.isEmpty(src)) {
            return;
        }

        Collections.sort(src, new Comparator<Object>() {

            @Override
            public int compare(Object o1, Object o2) {
                Object value1 = BeanUtil.pojo.getProperty(o1, field);
                Object value2 = BeanUtil.pojo.getProperty(o2, field);
                if (value1 != null && value2 != null) {
                    if (value1 instanceof Long) {
                        return ((Long) value1).compareTo((Long) value2) * direction;
                    }

                    if (value1 instanceof Integer) {
                        return ((Integer) value1).compareTo((Integer) value2) * direction;
                    }

                    if (value1 instanceof Double) {
                        return ((Double) value1).compareTo((Double) value2) * direction;
                    }

                    if (value1 instanceof BigDecimal) {
                        return ((BigDecimal) value1).compareTo((BigDecimal) value2) * direction;
                    }

                    if (value1 instanceof Date) {
                        return ((Date) value1).compareTo((Date) value2) * direction;
                    }

                    if (value1 instanceof String) {
                        return ((String) value1).compareTo((String) value2) * direction;
                    }
                }
                return 0;
            }
        });
    }

    /**
     * 除重
     *
     * @param src
     * @param <K>
     * @return
     */
    public static <K> List<K> distinct(List<K> src) {
        if (ValidateUtil.isEmpty(src)) {
            return src;
        }
        return new ArrayList<K>(src.stream().collect(Collectors.toSet()));
    }
}
发布了121 篇原创文章 · 获赞 116 · 访问量 39万+

猜你喜欢

转载自blog.csdn.net/Mr_EvanChen/article/details/103374963