首页 > 数据库 >分批查询SQL

分批查询SQL

时间:2024-09-06 16:38:16浏览次数:10  
标签:return 分批 partition List inputList param 查询 SQL

1. 背景

批量查询,如何入参数组参数过多,会导致SQL长度过长,数据库会拒绝查询

2. 解决方式

在代码的层面上,进行分批查询,例如2000个参数,分成1000一批来进行查询,但是又会有几个问题

  1. 不同类的查询,入参和出参均不同,有没有一种方式,可以兼容不同的出入参
  2. 全量查询sql会去重,分批查询,不同批次会查出重复的数据,如何去重

3. 编程代码

通过函数式编程,封装函数,根据不同的查询,传入不同的查询类,就不用每个方式单独写一次

新建函数式函数式接口

@FunctionalInterface
public interface DatabaseOperation<T, R> {

    /**
     * 分批操作
     *
     * @param partition
     * @return
     */
    R apply(List<T> partition);
}

封装函数

    /**
     * 分批次操作(增、删、改、查),最后合并结果 解决2048 问题,
     *
     * @param inputList 所有查询的列表
     * @param maxSize 分割数
     * @param operation mapper查询操作
     * @param distinctByKey 唯一值,用于去重,避免分批查询合并得结果有重复数据
     * @param <T>
     * @param <R>
     * @return
     */
    public static <T, R> List<R> executeInPartitions(List<T> inputList, int maxSize,
                                                     DatabaseOperation<T, List<R>> operation,
                                                     Function<? super R, ?> distinctByKey) {
        // 使用LinkedHashMap保留插入顺序,在去重时将会用到
        Map<Object, R> map = new LinkedHashMap<>();

        if (inputList == null || inputList.isEmpty()) {
            return new ArrayList<>(map.values());
        }
        // 将输入列表根据最大大小切割并执行操作
        for (int i = 0; i < inputList.size(); i += maxSize) {
            int end = Math.min(inputList.size(), i + maxSize);
            List<T> partition = inputList.subList(i, end);
            // 对每个分区执行数据库操作
            List<R> result = operation.apply(partition);
            if (result != null) {
                // 根据提供的键提取器去重并收集结果
                result.stream()
                        .collect(Collectors.toMap(distinctByKey, r -> r,
                                (existing, replacement) -> existing, LinkedHashMap::new))
                        .forEach((key, value) -> map.putIfAbsent(key, value));
            }
        }
        return new ArrayList<>(map.values());
    }

使用方式

List<Person> baseInfoList = ListUtils.executeInPartitions(personList, 1000,
                partition -> personMapper.getPerson(partition), Person::getId);

标签:return,分批,partition,List,inputList,param,查询,SQL
From: https://www.cnblogs.com/live2learn/p/18400508

相关文章

  • mysql为什么不推荐uuid做主键?
    在MySQL中,不推荐使用UUID作为主键的主要原因还是性能问题,其次是可读性差和浪费存储空间。性能问题:UUID是128位的字符串,通常被表示为32个字符的十六进制数。相比自增的整数(如AUTO_INCREMENT),UUID更大,占用的存储空间也更多,这会增加索引大小,导致查询变慢,尤其是在大表中。无序......
  • linux中安装mysql
    目录1,删除centos7自带的mariadb2,下载mysql3,安装4,修改密码5,远程登录1,删除centos7自带的mariadb查看是否有mariadbrpm-qa|grepmariadb删除rpm-e--nodepsmariadb-libs-5.5.68-1.el7.x86_64再看下没有输出,删除成功2,下载mysqlMySQL::Download......
  • 关于SqlServer中的表分区
    目录结构:什么是分区准备测试数据如何进行水平分区创建文件组创建分区函数创建分区方案创建分区表使用分区向导创建分区表秀一秀肌肉关于表分区的常用管理拆分分区合并分区查看指定数据所在的分区1.什么是分区在sqlserver中,一般情况下所有的数据都是存储到一......
  • ORCLE数据库语言设置原因查询不出数据的问题解决
    问题现象:oracle数据库视图中存在数据,但是jdbc查询视图查询不出来,后发现视图中有根据默认语言的过滤,如下图: 客户端查询环境语言为 web服务器查询环境语言为US,所以数据查询不出来。解决方案:修改应用端的NLS_LANG的配置与SQL保持一致linux执行下面代码exportNLS_LANG="......
  • sqlserver 用户权限设计
    一个用户拥有多个权限,下面是如何确保一个用户所有相关的权限都能被正确显示,并且每种type都会显示在查询结果中。例如,假设你有以下数据:USERS表: RolePermission表: checkItems表: 在这个示例中,userID=1对应的roleID是101,这使得查询会联......
  • sql之left join、right join、inner join的区别
    1、leftjoin(左联接)返回包括左表中的所有记录和右表中联结字段相等的记录2、rightjoin(右联接)返回包括右表中的所有记录和左表中联结字段相等的记录3、innerjoin(等值连接)只返回两个表中联结字段相等的行举例如下:--------------------------------------------表A记录如......
  • MySQL5.7.36之高可用架构部署-Atlas读写分离
    1、安装Atlas-2.2.1.el6.x86_64.rpmrpm-ivhAtlas-2.2.1.el6.x86_64.rpm2、进入Atlas目录并且备份配置文件cd/usr/local/mysql-proxy/confcptest.cnftest.cnf.bak3、密码加密采用的是自带的工具/usr/local/mysql-proxy/bin/encrypt123456#因为我的密码是1234564、......
  • Docker 容器技术:简化 MySQL 主从复制部署与优化
    文章目录前言一、为什么基于Docker搭建?二、利用Docker搭建主从服务器2.1配置Master(主)2.2配置Slave(从)2.3链接Master(主)和Slave(从)2.4测试主从复制三、常见问题3.1什么时候用读写分离?3.2MySQL主从复制原理3.3解决主从复制延迟有几种常见的方法?3.4造成mysql同步......
  • debian11 申通 无感考勤 mysql postgresql nacos集群
     echo"nameserver114.114.114.114nameserver8.8.8.8">/etc/resolv.conf echo"debhttps://mirrors.aliyun.com/debian/bullseyemainnon-freecontribdeb-srchttps://mirrors.aliyun.com/debian/bullseyemainnon-freecontribdebhttps://......
  • SQLServer 如何收集数据以排除 SQL 死锁问题
     方案一使用SQLProfiler跟踪工具捕获死锁数据:1.登录SQLServerManagementStudio2.单击工具、SQLServerProfiler,然后进行身份验证3.单击"事件选择"选项。4.取消选择所有选项。5.单击以下两个选项: ·显示所有列 ·显示所有事件框6.展开锁。7.选择以下内容: ·死锁图 ·锁......