如果不发出查询就不知道实体 ID,是否可以使用 spring-data-jpa 更新而不是插入实体?
Can an entity be updated instead of being inserted using spring-data-jpa when entity ID is not known without issuing a query?
我们有一个使用 Hibernate 实现的 Spring Boot/Data-JPA (1.3.3.RELEASE) 应用程序,其中读取 CSV 文件并将其插入到名为 table 的数据库中30=]。对于已经存在的记录,我们只是更新它们。
我们通过查询唯一键(三列的组合)来检索记录 ID,但这种方法对于 CSV 文件中的数千条记录效率低下。
我的问题是如何在不查询 table 的唯一键的情况下更新记录?如果我不查询 ID,那么将插入记录而不是更新。
我知道一种方法是检索所有记录并将它们的唯一键和 ID 对存储在地图中。非常感谢任何其他建议。代码如下,
注意:为简洁起见,它们被最小化了。
@Entity
@Table(name = "FIRE_CSV_UPLOAD",
uniqueConstraints={@UniqueConstraint(columnNames = {"account_number" , "account_type", "bank_client_id"})})
public class FireCsv {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@NotNull
@Column(name="account_number")
private String accountNumber;
@NotNull
@Column(name="account_type")
private String accountType;
@NotNull
@Column(name="bank_client_id")
private String bankClientIdNumber;
...
other fields/getters/setters
}
--
public interface FireCsvRepository extends JpaRepository<FireCsv, Long> {
@Query("select u from FireCsv u where u.accountNumber = :accountNumber and u.accountType = :accountType and u.bankClientIdNumber = :bankClientIdNumber ")
FireCsv findRecord(@Param("accountNumber") String accountNumber,
@Param("accountType") String accountType,
@Param("bankClientIdNumber") String bankClientIdNumber);
}
--
@Service
public class FireCsvServiceImpl implements FireCsvService {
other fields/methods
...
@Override
@Transactional
public FireCsv save(final FireCsv fireCsv) {
FireCsv existingFireCsv = fireCsvRepository.findRecord(fireCsv.getAccountNumber(), fireCsv.getAccountType(), fireCsv.getBankClientIdNumber());
// If record exist then mark as update, if not as insert
if (existingFireCsv != null) {
fireCsv.setId(existingFireCsv.getId());
fireCsv.setRecordStatus(CSVUploadRecordStatus.CSV_UPDATE.getStatus());
}
else {
fireCsv.setRecordStatus(CSVUploadRecordStatus.CSV_INSERT.getStatus());
}
fireCsv.setRecordStatusDate(new java.sql.Timestamp(new Date().getTime()));
return fireCsvRepository.save(fireCsv);
}
}
在决定进行更新或插入之前,您必须阅读,我认为没有办法解决它。
为了加快速度,您应该在数据库中添加索引
使用三列 "account_number"、"account_type"、"bank_client_id".
或者,您可以尝试使用 @IdClass 来使用复合 ID,如下所示
tutorial-jpa-composite-primary-key
JPA 提供程序应该自动为其创建索引。
我们有一个使用 Hibernate 实现的 Spring Boot/Data-JPA (1.3.3.RELEASE) 应用程序,其中读取 CSV 文件并将其插入到名为 table 的数据库中30=]。对于已经存在的记录,我们只是更新它们。 我们通过查询唯一键(三列的组合)来检索记录 ID,但这种方法对于 CSV 文件中的数千条记录效率低下。
我的问题是如何在不查询 table 的唯一键的情况下更新记录?如果我不查询 ID,那么将插入记录而不是更新。
我知道一种方法是检索所有记录并将它们的唯一键和 ID 对存储在地图中。非常感谢任何其他建议。代码如下,
注意:为简洁起见,它们被最小化了。
@Entity
@Table(name = "FIRE_CSV_UPLOAD",
uniqueConstraints={@UniqueConstraint(columnNames = {"account_number" , "account_type", "bank_client_id"})})
public class FireCsv {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@NotNull
@Column(name="account_number")
private String accountNumber;
@NotNull
@Column(name="account_type")
private String accountType;
@NotNull
@Column(name="bank_client_id")
private String bankClientIdNumber;
...
other fields/getters/setters
}
--
public interface FireCsvRepository extends JpaRepository<FireCsv, Long> {
@Query("select u from FireCsv u where u.accountNumber = :accountNumber and u.accountType = :accountType and u.bankClientIdNumber = :bankClientIdNumber ")
FireCsv findRecord(@Param("accountNumber") String accountNumber,
@Param("accountType") String accountType,
@Param("bankClientIdNumber") String bankClientIdNumber);
}
--
@Service
public class FireCsvServiceImpl implements FireCsvService {
other fields/methods
...
@Override
@Transactional
public FireCsv save(final FireCsv fireCsv) {
FireCsv existingFireCsv = fireCsvRepository.findRecord(fireCsv.getAccountNumber(), fireCsv.getAccountType(), fireCsv.getBankClientIdNumber());
// If record exist then mark as update, if not as insert
if (existingFireCsv != null) {
fireCsv.setId(existingFireCsv.getId());
fireCsv.setRecordStatus(CSVUploadRecordStatus.CSV_UPDATE.getStatus());
}
else {
fireCsv.setRecordStatus(CSVUploadRecordStatus.CSV_INSERT.getStatus());
}
fireCsv.setRecordStatusDate(new java.sql.Timestamp(new Date().getTime()));
return fireCsvRepository.save(fireCsv);
}
}
在决定进行更新或插入之前,您必须阅读,我认为没有办法解决它。
为了加快速度,您应该在数据库中添加索引 使用三列 "account_number"、"account_type"、"bank_client_id".
或者,您可以尝试使用 @IdClass 来使用复合 ID,如下所示 tutorial-jpa-composite-primary-key JPA 提供程序应该自动为其创建索引。