स्प्रिंग डेटा: "डिलीट बाय" समर्थित है?


99

मैं डेटाबेस एक्सेस के लिए स्प्रिंग जेपीए का उपयोग कर रहा हूं। मैं findByName और countByName जैसे उदाहरण ढूंढने में सक्षम हूं, जिसके लिए मुझे कोई विधि कार्यान्वयन नहीं लिखना है। मैं कुछ शर्त के आधार पर रिकॉर्ड के एक समूह को हटाने के लिए उदाहरण खोजने की उम्मीद कर रहा हूं।

क्या स्प्रिंग जेपीए डिलीटनामे-जैसे डिलीट को सपोर्ट करता है? किसी भी सूचक की सराहना की जाती है।

सादर और धन्यवाद

जवाबों:


184

पदावनत उत्तर (स्प्रिंग डेटा JPA <= 1.6.x) :

@Modifyingबचाव के लिए एनोटेशन। हालाँकि आपको अपने कस्टम SQL व्यवहार को प्रदान करने की आवश्यकता होगी।

public interface UserRepository extends JpaRepository<User, Long> {
    @Modifying
    @Query("delete from User u where u.firstName = ?1")
    void deleteUsersByFirstName(String firstName);
}

अपडेट करें:

स्प्रिंग डेटा के आधुनिक संस्करणों में JPA (> = 1.7.x) के लिए क्वेरी व्युत्पत्ति delete, removeऔर countसंचालन सुलभ है।

public interface UserRepository extends CrudRepository<User, Long> {

    Long countByFirstName(String firstName);

    Long deleteByFirstName(String firstName);

    List<User> removeByFirstName(String firstName);

}

2
@AndreyAtapin डाउनवोट क्योंकि यह अब एक अच्छा जवाब नहीं है। शायद इसे हटा दें? स्टैकओवरफ्लो दोषों में से एक सवाल में पुस्तकालयों से जुड़े संस्करण परिवर्तन / बगफिक्स को संभाल रहा है।
बेन जॉर्ज

1
@webgeek, मैं इस मुद्दे को हल करता था DELETE FROM x WHERE id = ?1 or parent_id = ?1। Btw, सुनिश्चित करें कि आपके पास एक प्रकार नहीं है parent__id(क्या आपके पास इरादे से दोगुना कम पानी है?)। यद्यपि आप एक देशी क्वेरी विकल्प का उपयोग क्यों करते हैं?
एंड्रे एतापिन

4
यहां तक ​​कि मैं 1.7.4 का उपयोग करता हूं, सफल विलोपन के लिए क्वेरी विधि के ऊपर
@ ट्रान्सैटेक्शनल

40
आमतौर पर, एक आवेदन में, आपके पास @ सेवा कक्षाएं / विधियां होंगी और वे रिपॉजिटरी को कॉल करेंगे। और @ सेवा सार्वजनिक विधियाँ ऐसी विधियाँ होनी चाहिए जो @ लेन-देन के रूप में चिह्नित हैं क्योंकि लेन-देन का उपयोग केस आधारित है। मतलब एक उपयोग के मामले को पूरी तरह से प्रतिबद्ध या रोलबैक करने की आवश्यकता है। प्रत्येक व्यक्तिगत रिपॉजिटरी तरीके नहीं। इसलिए कृपया रिपॉजिटरी के तरीकों पर @ ट्रांजेक्शनल का उपयोग न करें। लेकिन सेवा विधियों पर जो रिपॉजिटरी का उपयोग करते हैं।
user1567291

1
रेपो में @Transactional बनाने का अर्थ है कि अगर आप कई बार रेपो कॉल करते हैं, तो सर्विस के अंदर सर्विस का अलग-अलग लेन-देन होगा, इसलिए 1 क्वेरी के भीतर रोलबैक करें। यदि आप सेवा स्तर पर प्रदान करते हैं, तो आपका पूरा कार्य किसी भी त्रुटि पर रोलबैक होगा।
पी सतीश पात्रो

78

दिए गए विधि नाम का उपयोग करके डिलीट किए गए प्रश्नों की व्युत्पत्ति स्प्रिंग डेटा JPA के संस्करण 1.6.0.RC1 से शुरू होने का समर्थन किया जाता है । कीवर्ड removeऔर deleteसमर्थित हैं। वापसी मूल्य के रूप में एक संख्या या हटाए गए संस्थाओं की सूची के बीच चयन कर सकते हैं।

Long removeByLastname(String lastname);

List<User> deleteByLastname(String lastname);

7

यदि आप स्प्रिंग डेटा JPA और विशेष रूप से PartTreeJpaQueryवर्ग के स्रोत कोड पर एक नज़र डालते हैं , तो आप देखेंगे कि यह तत्काल करने की कोशिश कर रहा है PartTree। उस वर्ग के अंदर निम्न नियमित अभिव्यक्ति है

private static final Pattern PREFIX_TEMPLATE = Pattern.compile("^(find|read|get|count|query)(\\p{Lu}.*?)??By")

इंगित करना चाहिए कि क्या अनुमति है और क्या नहीं है।

बेशक अगर आप ऐसी कोई विधि जोड़ने की कोशिश करते हैं तो आप वास्तव में देखेंगे कि यह काम नहीं करता है और आपको पूरी तरह से स्टैक्ट्रेस मिल जाता है।

मुझे ध्यान देना चाहिए कि मैं 1.5.0.RELEASEस्प्रिंग डेटा जेपीए के संस्करण को देख रहा था


6

2 तरीके: -

1 एक कस्टम क्वेरी

@Modifying
@Query("delete from User where firstName = :firstName")
void deleteUsersByFirstName(@Param("firstName") String firstName);

दूसरी जेपीए क्वेरी विधि द्वारा

List<User> deleteByLastname(String lastname);

जब आप विधि द्वारा (2 तरीके) क्वेरी के साथ जाते हैं तो यह पहली बार एक कॉल करेगा

select * from user where last_name = :firstName

फिर इसे एक लिस्ट में लोड करेंगे फिर इसे एक के बाद एक डिलीट आईडी कहेंगे

delete from user where id = 18
delete from user where id = 19

पहले ऑब्जेक्ट की सूची प्राप्त करें, फिर एक-एक करके आईडी हटाने के लिए लूप

लेकिन, पहला विकल्प (कस्टम क्वेरी),

यह सिर्फ एक ही क्वेरी है यह जहाँ भी मौजूद है वहाँ हटा देगा।

इस लिंक पर जाएं https://www.baeldung.com/spring-data-jpa-deleteby


1
जानकारी के लिए धन्यवाद!
जिज्ञासु

2

यदि आप पूर्व निर्धारित हटाए गए तरीकों का उपयोग करेंगे जैसा कि सीधे वसंत जेपीए द्वारा प्रदान किया गया है, तो नीचे दो प्रश्नों को फ्रेमवर्क द्वारा निष्पादित किया जाएगा।

  • पहले डेटा (जैसे आईडी और अन्य कॉलम) इकट्ठा करें, जहां क्लॉज़ हटाएं क्वेरी के साथ चयन क्वेरी निष्पादित करके उपयोग करें।

  • फिर पहली क्वेरी के परिणाम को प्राप्त करने के बाद, दूसरी डिलीट क्वेरी को सभी आईडी (एक-एक करके) के लिए निष्पादित किया जाएगा।

    नोट: यह आपके आवेदन के लिए अनुकूलित तरीका नहीं है क्योंकि एकल MYSQL डिलीट क्वेरी के लिए कई प्रश्नों का निष्पादन किया जाएगा।

डिलीट क्वेरी कोड के लिए यह एक और अनुकूलित तरीका है क्योंकि नीचे दिए गए कस्टमाइज़्ड तरीकों का उपयोग करके केवल एक डिलीट क्वेरी निष्पादित होगी।



@NamedNativeQueries({

@NamedNativeQuery(name = "Abc.deleteByCreatedTimeBetween",
            query = "DELETE FROM abc WHERE create_time BETWEEN ?1 AND ?2")
    ,

    @NamedNativeQuery(name = "Abc.getByMaxId",
            query = "SELECT max(id) from abc")
})

@Entity
public class Abc implements Serializable {

}

@Repository
public interface AbcRepository extends CrudRepository {

    int getByMaxId();

    @Transactional
    @Modifying
    void deleteByCreatedTimeBetween(String startDate, String endDate);
}


1

जब आप बैच डिलीट के लिए व्युत्पन्न क्वेरी का उपयोग करते हैं तो केयरफुल बनें। यह वह नहीं है जिसकी आप अपेक्षा करते हैं: DeleteExecution


नमस्ते। यदि आप RBAR (agonizing row द्वारा पंक्ति) को इंगित कर रहे हैं, तो क्या आप इसे अपने उत्तर में जोड़ सकते हैं? (और मैं उत्थान करूंगा)। मैं थोड़े अनुमान लगा रहा हूं कि आप यहां क्या इशारा कर रहे हैं।
ग्रेनडाकर

0

हाँ, DeleteBy विधि समर्थित है इसका उपयोग करने के लिए आपको @Transactional के साथ विधि को एनोटेट करने की आवश्यकता है

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.