java - 根据数据库中的可用性插入/更新行

标签 java mysql hibernate jpa jdbc

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

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

我可以使用正常的名称选择查询并检查是否为空,并基于该插入或更新来完成此操作,但我有数千行要从 excel 文件中读取,并且请求的非功能性要求是性能

所以请告诉我处理这个 senario 的最佳方法是什么?我还没有开始编写我的持久层部分,所以我可以根据您的建议切换到 ORM 或纯 jdbc。

编辑: 如果我使用名称作为主键,那么我想我可以使用 saveOrUpdate 或从 ORM 合并来满足我的需要。这是不是一个好主意??? 感谢和问候, 普拉萨特。

最佳答案

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

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

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

create or replace directory data_dir as '/mydatadir/';
create table external_table (
  id number(18),
  name varchar2(30),
  otherfield1 varchar2(40),
  otherfield2 varchar2(40))
organization external (
  type oracle_loader
  default directory data_dir
  access parameters
  ( fields terminated by ',' )
  location ('mydata.csv')
)

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

然后你可以使用下面的命令来merge数据到你的表中:

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 的 SimpleJdbcTemplate )

编辑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,并且应该表现良好。这将允许您在没有外部表的情况下执行此操作(您需要名称列上的 UNIQUE 索引才能工作,我不会更改主键,因为如果您需要更改,这可能会导致外键出现问题某人的名字)。

MySQL也有external tables的概念,我认为这仍然比按上述方式批量插入数据更快。只要将 csv 文件上传到正确的位置,导入就会很快进行。

关于java - 根据数据库中的可用性插入/更新行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10100408/

相关文章:

Java Spring 散列和验证密码

java - 我如何在 Java 中比较字符串?

java - ByteBuddy - 读取 java 代理中的类注释

mysql - 计算查询表中的行数

java - 您可以将 JDBC 与代号一一起使用吗?

java - Hibernate 模式验证失败,MySQL CHAR 映射到 String

java - 数据库函数与其他列的Hibernate/JPA属性映射结果

java - 我怎样才能在我的类(class)中拥有 2 个相同类型的对象?

java - 无限循环,不会以while循环结束

MySQL MATCH 具有多个关键字