Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/321.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_Mysql_Hibernate_Jpa_Jdbc - Fatal编程技术网

Java 根据行在数据库中的可用性插入/更新行

Java 根据行在数据库中的可用性插入/更新行,java,mysql,hibernate,jpa,jdbc,Java,Mysql,Hibernate,Jpa,Jdbc,这是一个常见的场景,但我想知道哪种方式是性能优化方式和最佳实践 我有一个包含4列的表:id、name和其他两个字段。Id是主键,name是唯一键。我从excel文件中读取数据,填充域对象中每一行的值,然后保存它。保存时,我想查看是否已经存在同名记录,如果存在,我想更新它。否则将其另存为新记录 我可以用普通的select查询名称并检查null,根据插入或更新,但我有数千行要从excel文件中读取,请求的非功能性要求是性能 所以,请告诉我哪一个是处理这件事的最好方法?我还没有开始编写持久层部分,所以

这是一个常见的场景,但我想知道哪种方式是性能优化方式和最佳实践

我有一个包含4列的表:id、name和其他两个字段。Id是主键,name是唯一键。我从excel文件中读取数据,填充域对象中每一行的值,然后保存它。保存时,我想查看是否已经存在同名记录,如果存在,我想更新它。否则将其另存为新记录

我可以用普通的select查询名称并检查null,根据插入或更新,但我有数千行要从excel文件中读取,请求的非功能性要求是性能

所以,请告诉我哪一个是处理这件事的最好方法?我还没有开始编写持久层部分,所以我可以根据您的建议切换到ORM或普通jdbc

编辑: 若我使用name作为主键,那个么我想我可以从ORM中使用saveOrUpdate或merge来满足我的需要。这是个好主意吗??? 谢谢和问候,
Prasath.

读取集合中的所有名称并减去从excel文件读取的名称集合的使用组合可能是合理的

Set dbSet=//fill it from SQl query;
Set newSet//fill it from the file;

newSet.removeAll(dbSet); //left non existing ones to be inserted.
原始新闻集(可以是初始新闻集的克隆)


我认为最快的方法是在数据库本身中执行所有插入/更新,而不是连接到数据库并使用大量语句

注意,这是特定于Oracle的,但其他数据库可能有类似的概念

我将使用以下方法:首先将Excel数据保存为数据库服务器上的CSV文件(
/mydatadir/mydata.CSV
),然后在Oracle中使用:

(注意,不必每次都设置外部表)

然后,您可以使用以下命令将数据添加到表中:

merge into yourtable t
using external_table e
on t.name = e.name
when matched then
   update set t.id = e.id, 
              t.otherfield1 = e.otherfield1, 
              t.otherfield2 = t.otherfield2
when not matched then
   insert (t.id, t.name, t.otherfield1, t.otherfield2)
   values (e.id, e.name, e.otherfield1, e.otherfield2)
这将在一个Oracle命令中向上插入
yourtable
中的行,因此所有工作都将由数据库执行

编辑:

这个
merge
命令可以通过普通JDBC发出(尽管我更喜欢使用Spring的)

编辑2:

在MySQL中,可以使用以下构造执行合并:

insert into yourtable (id, name, otherfield1, otherfield2)
values (?, ?, ?, ?), 
       (?, ?, ?, ?), 
       (?, ?, ?, ?) --repeat for each row in the Excel sheet...
on duplicate Key update
set otherfield1 = values(otherfield1),
    otherfield2 = values(otherfield2)
这可以作为一个普通的JDBC语句发布,并且比单独的更新和插入更好,您可以从电子表格中批量调用(比如)一百行。这意味着Excel工作表中每100行调用1个JDBC,并且应该表现良好。这将允许您在不使用外部表的情况下执行此操作(您需要在name列上使用唯一索引才能执行此操作,我不会更改主键,因为如果您需要更改某人的姓名,这可能会导致外键出现问题)


MySQL还具有的概念,我认为这比按照上述方法批量插入数据还要快。只要csv文件上传到正确的位置,导入就应该能够快速工作

很好的建议,但我需要通过java程序来实现,所以在这样的程序中寻找最佳实践…:)@用户495939您可以从Java执行
合并
查询,就像执行
插入
更新
(说到这一点:有些数据库支持
更新或插入
,其功能类似于合并,但插入/更新单个行时更容易。@当对象具有主键值时,ORM中的Mark Rottevel merge将更新类似行。我要问的是,我用excel fi中某一行的数据填充对象le,当我插入它时,我需要检查是否有类似的行,然后更新。如果该对象有id值,我可以使用“合并”,但由于它是一个新填充的对象,它的id列没有任何值,所以我怀疑合并是否有效。@user495939:ORM的saveOrUpdate通常不会检查行是否已经存在但是根据ID值是否已填充,使用INSERT或UPDATE。@beny23:正是我要找的…非常感谢…:d这意味着您必须有足够的内存将所有现有数据和新数据保存在内存中,这对于大型数据集来说可能是不可能的。
merge into yourtable t
using external_table e
on t.name = e.name
when matched then
   update set t.id = e.id, 
              t.otherfield1 = e.otherfield1, 
              t.otherfield2 = t.otherfield2
when not matched then
   insert (t.id, t.name, t.otherfield1, t.otherfield2)
   values (e.id, e.name, e.otherfield1, e.otherfield2)
insert into yourtable (id, name, otherfield1, otherfield2)
values (?, ?, ?, ?), 
       (?, ?, ?, ?), 
       (?, ?, ?, ?) --repeat for each row in the Excel sheet...
on duplicate Key update
set otherfield1 = values(otherfield1),
    otherfield2 = values(otherfield2)