目前我正在开发一个 Spring-Boot 应用程序,该应用程序定期尝试处理包含用户数据的文件,其中每行都包含userId
and departamentId
隔开|
例如123534|13
。该文件将包含数百万条记录。
我的要求是以这样的方式将此数据加载到 mysql 数据库中:
- 如果处理过的ID的用户存在,不要做任何事
- 如果用户不存在create新用户
- 如果用户不在列表中但存在于数据库中,去掉它
- 如果数据库中不存在当前部门,创造它
我做了一些优化,比如
- 缓存部门以填充实体
- 批量收集用户进行保存并通过保存
JpaRepository
saveAll
method
但我仍然对数据库进行了太多的数据库调用,我正在检查用户是否存在,以便为每条记录创建保存实体......
我的实体相当简单:
@Entity
@Table(name = "departaments")
public class Departament{
@Id
@Column(name = "id")
private Long id;
@Column(name = "name")
private String name;
and:
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@ManyToOne
@JoinColumn(name = "departament_id")
private Departament departament;
有人遇到过这样的问题吗?
能不能再优化一下?
有什么好的加工模式吗?
这里有几件事:
- 对于用户来说,您的主要真实来源似乎是 CSV 文件。为什么不简单地截断并重新创建
USER
桌子?您可能会遇到一些问题(我理解引用完整性是not在你的场景中其中之一 - 或者是?),但你将免费删除用户(说实话,我无法完全想象你如何在当前设置中处理用户删除)。它会跑得更快禁用密钥检查 https://stackoverflow.com/questions/8210608/mysql-disable-enable-keys
- 您在使用时是否确实看到了性能改进
saveAll
?这不限制数量SELECT
要执行的语句
- 您确定您在正确的抽象级别上操作吗?也许您可以使用普通 JDBC 而不是 JPA。使用 JPA,将会涉及大量的缓存/映射,从而导致大量的开销。通过 JDBC,您可以利用 MySQL 的
INSERT IGNORE
or INSERT ... ON DUPLICATE KEY UPDATE
声明以获得你想要的东西
- 如果您选择上述任何一种,您可以尝试使用春季批次 https://www.petrikainulainen.net/programming/spring-framework/spring-batch-tutorial-writing-information-to-a-database-with-jdbc/用于更多声明性处理
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)