2 baidu 37252709 baidu_37252709 于 2018.03.09 09:58 提问

java 每从数组里面获取1000条数据

批量删除用户,传过来的是一个integer[] ids,长度0~100万不定,当数据量大的时候删除太慢或者删除不了,现在想每次删1000条,时间长点可以接受,想知道怎么每次从ids取1000条,或者其他有更好的方案也可以,删除用户需要删除关联的东西太多,不能直接用sql in来删

12个回答

roc168
roc168   2018.03.09 10:38
已采纳

参考如下示例代码:

 package com.example.test;

import java.util.Arrays;

public class Test {
    public static void main(String[] args) {
        int maxRange = 2600;
        int[] ids = new int[maxRange];
        for (int i = 0; i < maxRange; i++) {
            ids[i] = i;
        }

        int PER_QUERY_COUNT = 1000; //每次查询数量

        int from = 0; //起始索引
        int to = PER_QUERY_COUNT; //结束索引

        for (int j = 0; j < ids.length; j += PER_QUERY_COUNT) {
            //将一个原始的数组original,从小标from开始复制,复制到小标to,生成一个新的数组。
            // 注意这里包括下标from,不包括下标to。
            System.out.println("from=" + from + ",to=" + to);
            int[] temp = Arrays.copyOfRange(ids, from, to);
            for (int id : temp) {
                System.out.print(id + ",");
            }
            from += PER_QUERY_COUNT;
            to += PER_QUERY_COUNT;
            if (to > ids.length) {
                to = ids.length;
            }
            System.out.println("\r");
        }
    }
}

baidu_30233079
baidu_30233079   2018.03.09 10:11

System.arraycopy

fairy_gg
fairy_gg   2018.03.09 10:15

什么数据库?根据区间删除呢?

greeeeeeeeen
greeeeeeeeen   2018.03.09 10:38

System.arraycopy就可以了

c1542793315
c1542793315   2018.03.09 10:50

根据数组索引进行取值,

wap55
wap55   2018.03.09 10:56

可以用SQL语句的exists或者not exists来进行删除,这个效率比in或者not in快,数据库里面去操作更方便一点。

qq_38145167
qq_38145167   2018.03.09 11:30

案例 :如下图图片说明 打印出来的结果 图片说明

qq_34078582
qq_34078582   2018.03.09 15:22

批量删除目前我知道的只能用in,

一般是在service层把addsql拼好,
然后在持久层用类似Delete from 'table' where id in (addsql),
至于in()这里能放多少条,要看数据库了。
据说oracle 1000 条,sqlserver 更多

下面的代码是把数组分页处理,为了符合sql in()里的要求,每1000个id,变成用‘,’分开的字符串赋给addsql。
需要注意:
下面是service层的代码。
PAGESIZE可以自己根据具体情况调整

ps:我一般都用list,几乎没有用过数组。list的底层也是数组。我觉得list能满足更多的需求,以后还是多用list吧

private static final int PAGESIZE = 1000;//可调
public void delete(Integer[] ids) {
Dao dao = new Dao();//这里声明dao
if (ids != null && ids.length > 0) { //判空
int num = 1; //页码
int index = 0; //当前是哪一条
while (ids.length > index) {
if (ids.length > num * PAGESIZE) {
Integer[] idstemp = Arrays.copyOfRange(ids, (num-1) * PAGESIZE, num * PAGESIZE);//截取1000条
String addsql = ArrayToString(idstemp);//把1000个数字转换用“,” 分隔的字符串 比如:1,5,65,897。
dao.DeleteInfoById(appsql);//把上面的字符串传到dao层 ,然后Delete from 'table' where id in (addsql) 这里是1000个。可以自己调
index = num* PAGESIZE;
num++;//下一页
} else {
Integer[] idstemp = Arrays.copyOfRange(ids, (num-1) * PAGESIZE, ids.length);//当最后一页的数量大于剩余数量,取剩余数量
String appsql = ArrayToString(idstemp);//同上
dao.DeleteInfoById(appsql);//同上
index = ids.length;//最后一条
}
}
}
}

private String ArrayToString(Integer[] idstemp) {  //把数组中的数字用‘,’隔开,返回字符串 比如:456,45646,45646,77543
    if (idstemp != null && idstemp.length > 0) {
        String str = "";
        for (int i : idstemp) {
            str = str + i + ",";
        }
        return str.substring(0, str.length() - 1);
    }
    return "";
}
qq_34078582
qq_34078582 。。。。第一次写评论 ,不知道调代码样式。。。在哪删
4 个月之前 回复
weixin_41780614
weixin_41780614   2018.03.09 17:10

声明一个ArrayList al;
for(int i ;i<ids.length;i++){
if(i % 1000 != 0){
将ids中的第i数据放入al;
}else{
将al的数据在数据库中处理
初始化al.
}
}

如果al不空,则 将al的数据在数据库中处理

maiyikai
maiyikai   2018.03.12 14:33

这个问题真难,使用数组处理这么大的数据量,根本就是想都不用想的嘛,;使用数据库的时候,直接根据你传入的id获取其他主键标识去删就行了,,分不分批都是由你控制的;

共12条数据 1 尾页
Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!