題
如果我使用 宣告了我的(復合)主鍵@IdClass,我該如何撰寫 my@Query以便能夠使用 發出DELETE查詢Collection<MyIdClass>?
次要問題
AnotherEntity盡管使用了 CASCADE 實際上會觸發關聯的洗掉@Query嗎?
當前型號
@Entity
@Table(name = "myentity")
@JsonIgnoreProperties(ignoreUnknown = true)
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@IdClass(MyIdClass.class)
public class MyEntity {
@Id
@Column(updatable = false)
private String foo;
@Id
@Column(updatable = false)
private String bar;
@OneToOne(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "my_foreign_key", referencedColumnName = "external_pk")
private AnotherEntity anotherEntity;
}
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class MyIdClass implements Serializable {
private String foo;
private String bar;
}
@Entity
@Table(name = "anotherentity")
@JsonIgnoreProperties(ignoreUnknown = true)
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public class AnotherEntity {
@Id
@Column(name = "external_pk", nullable = false, updatable = false)
private String externalPk;
}
我讀過的
一些資源:
- https://www.baeldung.com/spring-data-jpa-query
- https://www.baeldung.com/spring-data-jpa-delete
- https://stackoverflow.com/a/36765129/9768291
而且我還發現這個 SO question似乎非常接近我正在尋找的問題,但不幸的是沒有答案。
目標
類似于:
@Repository
public interface MyCRUDRepository extends CrudRepository<MyEntity, MyIdClass> {
@Modifying
@Query("DELETE FROM myentity m WHERE m IN ?1") // how do I write this?
void deleteAllWithIds(Collection<MyIdClass> ids);
}
最終,我想這樣做來批處理我的 DELETE 請求以提高性能。
我試圖避免的陷阱
I know there is a deleteAll(Iterable<? extends MyEntity>) but then I need to actually have those entities to begin with, which would require extra calls to the DB.
There is also deleteById(MyIdClass), but that actually always issues a findById before sending a single DELETE statement as a transaction: not good for the performance!
Potentially irrelevant precision
I'm not sure if that can help, but my JPA provider is EclipseLink. My understanding is that there are properties for batching requests, and that's ultimately what I'm aiming to use.
但是,我不完全確定要進行批處理的內部要求是什么。例如,如果我在 adeleteById中做了a for-loop,交替SELECT和DELETE陳述句會阻止批處理的發生嗎?關于這一點的檔案非常少。
uj5u.com熱心網友回復:
我認為您正在尋找會生成這樣的查詢的東西
delete from myentity where MyIdClass in (? , ? , ?)
你可以試試這個帖子,它可能對你有幫助。
uj5u.com熱心網友回復:
如果您確定在您的情況下 IdClass 是比 EmbeddedId 更好的選擇,您可以添加一個額外的映射到 MyEntity :
@Embedded
@AttributeOverrides({
@AttributeOverride(name = "foo",
column = @Column(name = "foo", insertable = false, updatable = false)),
@AttributeOverride(name = "bar",
column = @Column(name = "bar", insertable = false, updatable = false))})
private MyIdClass id;
并在您的存盤庫中使用它:
@Modifying
@Query("DELETE FROM MyEntity me WHERE me.id in (:ids)")
void deleteByIdIn(@Param("ids") Collection<MyIdClass> ids);
這將生成一個查詢:delete from myentity where bar=? and foo=? [or bar=? and foo=?]...,導致此測驗通過(具有下表記錄insert into myentity(foo,bar) values ('foo1', 'bar1'),('foo2', 'bar2'),('foo3', 'bar3'),('foo4', 'bar4');):
@Test
@Transactional
void deleteByInWithQuery_multipleIds_allDeleted() {
assertEquals(4, ((Collection<MyEntity>) myEntityRepository.findAll()).size());
MyIdClass id1 = new MyIdClass("foo1", "bar1");
MyIdClass id2 = new MyIdClass("foo2", "bar2");
assertDoesNotThrow(() -> myEntityRepository.deleteByIdIn(List.of(id1, id2)));
assertEquals(2, ((Collection<MyEntity>) myEntityRepository.findAll()).size());
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/339853.html
上一篇:看不到2個資料幀之間的區別
下一篇:Java:集合映射中的重復列
