Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/88.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
获取Java数据库中不存在的对象列表的有效方法_Java_Sql - Fatal编程技术网

获取Java数据库中不存在的对象列表的有效方法

获取Java数据库中不存在的对象列表的有效方法,java,sql,Java,Sql,假设我有一个对象列表ArrayList对象和一个对象的db表,我想查找尚未存储在my数据库中的对象。对象由其id标识。我可以想出两种解决方案,但我不知道哪一种更有效 我想到的第一个解决方案是构造一个db查询,以获取db中存在的所有对象,并循环遍历现有对象以确定不在db中的对象 ArrayList<Integer> ids = new ArrayList<Integer>(); for(MyObject o in objects){ ids.add(o.getId

假设我有一个对象列表ArrayList对象和一个对象的db表,我想查找尚未存储在my数据库中的对象。对象由其id标识。我可以想出两种解决方案,但我不知道哪一种更有效

我想到的第一个解决方案是构造一个db查询,以获取db中存在的所有对象,并循环遍历现有对象以确定不在db中的对象

ArrayList<Integer> ids = new ArrayList<Integer>();
for(MyObject o in  objects){
    ids.add(o.getId());
}

//I use sugar orm on Android, raw query can be seen as 
// "select * from my_object where id in [ id1,id2,id3 .....  ]"
List<MyObjectRow> unwanted_objects = MyObject.find("id in (?,?,?,?,.....)",ids);

//remove the query results from the original arraylist
for(MyObjectRow o in  unwanted_objects){
     for(MyObject o1 in  objects){
         if(o1.getId() == o.getId()) objects.remove(o1);

     }
}
第二种解决方案是查询数据库中每个对象是否存在,并将不存在的对象添加到结果数组中

ArrayList<MyObject> result_objects = new ArrayList<MyObject>();

boolean exist = false
for(MyObject o in  objects){
       exist = MyObject.find("EXIST( select 1 from my_object where id = ?)", o.getId());
       if(!exist){
           result_objects.add(o);
       }
}
第一个解决方案只需要一个查询,但当循环遍历所有已建立的对象时,复杂性变为*n

第二个解决方案构造了n个db查询,但它的复杂性只有On


哪一个性能更好?

您不知道数据库操作的效率。如果数据库是一个隐藏的b-树,那么该查询可能需要OLOGN。如果您的索引设置不正确,您可能正在查看该查询的性能。这里对效率的衡量也忽略了任何事务成本:启动与数据库的连接、处理查询和关闭与数据库的连接的成本。这是一个“固定”成本,如果不是必须的话,我不想在循环中这样做


使用第一种解决方案。

我将使用选项1,并更改为使用映射,以提高从原始列表中删除查询结果的性能:

List<Integer> ids = new ArrayList<Integer>();
Map<Integer, MyObject> mapToInsert = new HashMap<Integer, MyObject>();
for(MyObject o in  objects) {
    //add the ids of the objects to possibly insert
    ids.add(o.getId());
    //using the id of the object as the key in the map
    mapToInsert.put(o.getId(), o);
}

//retrieve the ids of the elements that already exist in database
List<MyObjectRow> unwanted_objects = MyObject.find("id in (?,?,?,?,.....)",ids);

//remove the query results from the map, not the list
for(MyObjectRow o in unwanted_objects){
     mapToInsert.remove(o.getId());
}

//insert the values that still exist in mapToInsert
Collection<MyObject> valuesToInsert = mapToInsert.values();

使用选项1和集合或映射(而不是列表)将其更改为“开”。投票@Luiggimendoza感谢各位提供了简单但伟大的解决方案。您将搜索多少条记录?我不知道in子句中是否有一些限制,但如果您要搜索数百万个对象,它将根本不起作用。最好的解决方案可能是将两种解决方案结合起来。使用in子句进行搜索,但只搜索有限数量的os对象(最多1000个),并循环直到搜索完所有对象。您可以在循环之前打开连接,执行必要的语句,然后在循环之后关闭连接,其影响小于您描述的场景。选项1本身也不是正确的方法,但它比选项2好。是的,但我不知道他正在使用的ORM在幕后做什么。我也不知道,无论你使用的是什么ORM或JDBC之上的框架,概念都是一样的