pop*_*der 5 java mysql hibernate jpa jdbc
这是一种常见的情况,但我想找出性能优化方式和最佳实践的方法.
我有一个包含4列的表:id,name和另外两个字段.Id是PK,名称是唯一键.我正在从excel文件中读取数据,填充Domain对象中每行的值,然后保存它.保存时,我想查看是否已存在同名的记录,如果存在,我想更新它.否则将其保存为新记录.
我可以使用正常的选择查询来查找名称并检查null,并根据插入或更新但我有数千行要从excel文件中读取,并且要求的非功能性要求是性能.
那么请告诉我哪个是处理这个Senario的最佳方法?我还没有开始编写我的持久层部分,所以我可以根据你的建议切换到ORM或普通的jdbc.
编辑:如果我使用名称作为主键,那么我想我可以使用saveOrUpdate或从ORM合并,以满足我的需要.这是不是一个好主意???谢谢和问候,Prasath.
我认为最快的方法是在数据库本身中执行所有插入/更新,而不是连接到数据库并使用大量语句。
请注意,这是 Oracle 特定的,但其他数据库可能有类似的概念。
我将使用以下方法:首先将 Excel 数据保存为数据库服务器 ( /mydatadir/mydata.csv
) 上的 CSV 文件,然后在 Oracle 中我将使用外部表:
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')
)
Run Code Online (Sandbox Code Playgroud)
(注意,外部表不必每次都设置)
然后您可以使用以下命令将数据合并到表中:
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)
Run Code Online (Sandbox Code Playgroud)
这将在一个 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)
Run Code Online (Sandbox Code Playgroud)
这可以作为普通 JDBC 语句发出,并且比单独的更新和插入更好,并且您可以从电子表格中批量调用(例如)一百行。这意味着 Excel 工作表中每 100 行需要 1 次 JDBC 调用,并且性能应该良好。这将允许您在没有外部表的情况下完成此操作(您需要在名称列上有一个唯一索引才能工作,我不会更改主键,因为如果您需要更改,这可能会导致外键出现问题某人的名字)。
MySQL也有外部表的概念,我认为这比上面批量插入数据更快。只要将 csv 文件上传到正确的位置,导入就会很快进行。
归档时间: |
|
查看次数: |
2007 次 |
最近记录: |