2010-10-07 23 views
61

मैं जेपीए/हाइबरनेट, स्प्रिंग और विकेट के आधार पर एक नया ऐप डिज़ाइन कर रहा हूं। डीएओ और सेवा परतों के बीच भेद हालांकि मुझे स्पष्ट नहीं है। विकिपीडिया के अनुसार, डीएओडीएओ और सर्विस लेयर (जेपीए/हाइबरनेट + स्प्रिंग)

एक वस्तु है कि, डेटाबेस या हठ तंत्र के कुछ प्रकार के लिए एक सार इंटरफेस प्रदान करता है डेटाबेस का विवरण प्रकट किए बिना कुछ विशिष्ट कार्यों प्रदान कर रहा है।

मैं सोच रहा था कि क्या डीएओ में ऐसी विधियां हो सकती हैं जो डेटा एक्सेस के साथ वास्तव में बहुत कुछ नहीं कर पाती हैं, लेकिन किसी क्वेरी का उपयोग करके आसान तरीके से निष्पादित किया जाता है? उदाहरण के लिए "सभी एयरलाइंस की एक सूची प्राप्त करें जो हवाई अड्डे के एक निश्चित सेट पर काम करती है"? यह मुझे सेवा-परत विधि के अधिक होने के लिए लगता है, लेकिन मुझे यकीन नहीं है कि सेवा परत में जेपीए EntityManager का उपयोग करना अच्छा अभ्यास का एक उदाहरण है?

उत्तर

51

एक डीएओ कैसे जटिल अपने व्यापार मॉडल के आधार पर डेटा का एक संबंधित स्रोत के लिए पहुँच प्रदान करना चाहिए और, या तो संपूर्ण व्यापार वस्तुओं, या सरल डाटा वस्तुओं वापस आ जाएगी। किसी भी तरह से, डीएओ विधियों को कुछ हद तक डेटाबेस को प्रतिबिंबित करना चाहिए।

एक सेवा न केवल आपके व्यावसायिक वस्तुओं को संसाधित करने के लिए एक उच्च स्तरीय इंटरफ़ेस प्रदान कर सकती है, बल्कि पहले स्थान पर पहुंच प्राप्त करने के लिए। अगर मुझे किसी सेवा से व्यवसाय ऑब्जेक्ट मिलता है, तो वह ऑब्जेक्ट अलग-अलग डेटाबेस (और विभिन्न डीएओ) से बनाया जा सकता है, इसे HTTP अनुरोध से की गई जानकारी से सजाया जा सकता है। इसमें कुछ व्यावसायिक तर्क हो सकते हैं जो कई डेटा ऑब्जेक्ट्स को एकल, मजबूत, व्यावसायिक ऑब्जेक्ट में परिवर्तित करता है।

मैं आम तौर पर एक डीएओ सोचता हूं कि इसका उपयोग किसी भी डेटाबेस द्वारा किया जाएगा, जो उस डेटाबेस का उपयोग करने जा रहा है, या व्यापार से संबंधित डेटा सेट है, यह सचमुच डेटाबेस के भीतर ट्रिगर्स, फ़ंक्शंस और संग्रहीत प्रक्रियाओं के अलावा निम्नतम स्तर कोड है।

विशिष्ट प्रश्नों के उत्तर:

मैं सोच रहा था कि क्या एक डीएओ तरीकों कि वास्तव में नहीं है डेटा का उपयोग के साथ ज्यादा करने के लिए हो सकता है, लेकिन जिस तरह से एक क्वेरी का उपयोग आसान मार डाला ?

ज्यादातर मामलों के लिए, आप अपनी सेवा परत में अधिक जटिल व्यापार तर्क, अलग-अलग प्रश्नों से डेटा की असेंबली चाहते हैं। हालांकि, यदि आप प्रसंस्करण गति के बारे में चिंतित हैं, तो एक सेवा परत एक डीएओ को एक क्रिया का प्रतिनिधि दे सकती है, भले ही यह मॉडल की सुंदरता को तोड़ देती है, वैसे ही एक सी ++ प्रोग्रामर कुछ क्रियाओं को गति देने के लिए असेंबलर कोड लिख सकता है।

यह एक सेवा परत विधि का अधिक होना मेरे लिए लगता है, लेकिन अगर सेवा परत में जेपीए EntityManager का उपयोग कर अच्छा अभ्यास का एक उदाहरण है मुझे यकीन है कि नहीं कर रहा हूँ?

आप अपनी सेवा में अपनी इकाई प्रबंधक का उपयोग करने जा रहे हैं, तो अपने डीएओ रूप में संस्था प्रबंधक के बारे में सोच है, क्योंकि यह है कि यह वास्तव में क्या है। यदि आपको कुछ अनावश्यक क्वेरी बिल्डिंग को हटाने की आवश्यकता है, तो अपनी सेवा कक्षा में ऐसा न करें, इसे उस वर्ग में निकालें जो इकाई प्रबंधक का उपयोग करता है और इसे आपके डीएओ बनाता है। आपके उपयोग के मामले बहुत आसान है, तो आप सेवा परत पूरी तरह छोड़ सकते हैं और नियंत्रकों में आपके इकाई प्रबंधक, या डीएओ इस्तेमाल कर सकते हैं, क्योंकि सभी आपकी सेवा करने जा रहा है डीएओ के findAirplaneById()

अद्यतन करने के लिए getAirplaneById() के लिए कॉल पास है - करने के लिए नीचे दी गई चर्चा के संबंध में स्पष्ट करें, किसी सेवा में किसी इकाई प्रबंधक का उपयोग करने की संभावना अधिकांश स्थितियों में सबसे अच्छा निर्णय नहीं है, जहां टिप्पणियों में हाइलाइट किए गए विभिन्न कारणों के लिए डीएओ परत भी होती है। लेकिन मेरी राय में यह पूरी तरह उचित दी जाएगी:

  1. सेवा डेटा के विभिन्न सेट के साथ बातचीत करने की जरूरत है
  2. कम से कम एक डेटा का सेट पहले से ही एक डीएओ
  3. सेवा वर्ग एक मॉड्यूल में रहता है जिसके लिए कुछ दृढ़ता की आवश्यकता होती है जो कि अपने स्वयं के डीएओ

उदाहरण के लिए पर्याप्त नहीं है।

//some system that contains all our customers information 
class PersonDao { 
    findPersonBySSN(long ssn) 
} 

//some other system where we store pets 
class PetDao { 
    findPetsByAreaCode() 
    findCatByFullName() 
} 

//some web portal your building has this service 
class OurPortalPetLostAndFoundService { 

    notifyOfLocalLostPets(Person p) { 
     Location l = ourPortalEntityManager.findSingle(PortalUser.class, p.getSSN()) 
     .getOptions().getLocation(); 
     ... use other DAO's to get contact information and pets... 
    } 
} 
+1

इस तरह के विस्तृत उत्तर के लिए धन्यवाद। मुझे आश्चर्य है: क्या दोनों के पास डीएओ का संग्रह होना चाहिए और सेवा परत में EntityManager का उपयोग करना ठीक होगा? –

+0

मुझे नहीं लगता कि इसमें कुछ भी गलत है, ध्यान रखें कि बोहोजो ने सेवा परत के बारे में क्या कहा था, जो कि अज्ञेयवादी थे। अगर चीजें तुच्छ से कम हो जाती हैं, तो मेरे पास सिर्फ एक ही डीएओ होगा जो इकाई प्रबंधक का उपयोग करता है और सभी इकाइयों के साथ सौदों का उपयोग करता है। मुझे कभी भी सामान्य पैटर्न के लिए कोई उपयोग नहीं मिला है जहां एक डीएओ किसी इकाई या टेबल के लिए विशिष्ट है, मुझे लगता है कि कक्षा डीएओ को डेटाबेस के लिए बाध्य होना चाहिए, अगर वर्ग बड़ा हो जाता है, तो यह स्पष्ट होता है कि यह अनावश्यक है कि – walnutmon

+0

ठीक है। मैंने ज्यादातर डीएओ को देखा है जो कसकर एक इकाई/टेबल के साथ मिलकर थे और सोचा था कि uncoupling अच्छा अभ्यास का उल्लंघन होगा। तो क्यूवर्की के जवाब में विधि AAOOperatingFrom() प्राप्त करें ठीक है? –

0

दाओ डेटा एक्सेस ऑब्जेक्ट है। यह डेटाबेस पर इकाइयों को संग्रह/अद्यतन/चयन करता है। इकाई प्रबंधक ऑब्जेक्ट का उपयोग उस के लिए किया जाता है (कम से कम खुले जेपीए में)। आप इस इकाई प्रबंधक के साथ क्वेरी भी चला सकते हैं। यह कोई एसक्यूएल नहीं है लेकिन जेपीक्यूएल (जावा दृढ़ता क्वेरी भाषा)।

सरल उदाहरण:

emf = Persistence.createEntityManagerFactory("localDB"); 
em = emf.createEntityManager(); 

Query q = em.createQuery("select u from Users as u where u.username = :username", Users.class); 
q.setParameter("username", username); 

List<Users> results = q.getResultList(); 

em.close(); 
emf.close(); 
14

एक बात निश्चित है: अगर आप सेवा परत पर EntityManager उपयोग करते हैं, आप एक दाव परत की जरूरत नहीं है (केवल एक परत कार्यान्वयन विवरण पता होना चाहिए)। इसके अलावा, वहाँ अलग राय हैं:

  • कुछ लोग कहते हैं EntityManager को उजागर करता है सभी आवश्यक दाव कार्यक्षमता, तो वे सेवा परत में EntityManager इंजेक्षन ।
  • अन्य में पारंपरिक दाओ परत इंटरफेस द्वारा समर्थित है (इसलिए सेवा परत कार्यान्वयन विवरण से जुड़ी नहीं है)।

दूसरा दृष्टिकोण और अधिक सुरुचिपूर्ण जब यह चिंताओं की जुदाई के लिए आता है और यह भी (तुम सिर्फ नई तकनीक से दाव इंटरफेस को फिर से लागू करने के लिए है) अन्य आसान करने के लिए एक सतत प्रौद्योगिकी से स्विच कर देगा, लेकिन अगर आप जानते हैं कि कुछ भी नहीं बदलेगा, तो पहला आसान है।

मैं कहूंगा कि आपके पास एक छोटी परियोजना है, सेवा परत में जेपीए का उपयोग करें, लेकिन एक बड़ी परियोजना में एक समर्पित डीएओ परत का उपयोग करें।

+0

आपके उदाहरण में इकाई प्रबंधक पहले उदाहरण में आपका डीएओ – walnutmon

+0

है, हाँ –

+1

+1। वास्तव में बड़ी परियोजनाओं में सेवा परत दृढ़ता-तंत्र अज्ञात होना चाहिए। – Bozho

4

परंपरागत रूप से आप इंटरफेस लिखेंगे जो आपकी सेवा परत और डेटा परत के बीच अनुबंध को परिभाषित करते हैं। फिर आप कार्यान्वयन लिखते हैं और ये आपके डीएओ हैं।

आपके उदाहरण पर वापस जाएं। एयरपोर्ट और एयरलाइन के बीच संबंधों को मानना ​​कई लोगों के लिए है जो एयरलाइन_आईडी और एयरलाइन_आईडी युक्त टेबल के साथ हैं, जिनके पास इंटरफ़ेस हो सकता है;

public interface AirportDAO 
{ 
    public List<Airline> getAirlinesOperatingFrom(Set<Airport> airports); 
} 

..और आप इसका एक हाइबरनेट कार्यान्वयन प्रदान कर सकते हैं;

public class HibernateAirportDAO implements AirportDAO 
{ 
    public List<Airline> getAirlinesOperatingFrom(Set<Airport> airports) 
    { 
     //implementation here using EntityManager. 
    } 
} 

आप भी अपनी एयरलाइन इकाई पर एक सूची होने और एक @ManyToMany जेपीए एनोटेशन के साथ संबंध को परिभाषित करने पर विचार कर सकता है। यह इस विशेष डीएओ विधि को पूरी तरह से रखने की आवश्यकता को हटा देगा।

आप डीएओ कारखानों को लिखने के लिए सार फैक्टरी पैटर्न को भी देखना चाहते हैं। उदाहरण के लिए;

public abstract class DAOFactory 
{ 
    private static HibernateDAOFactory hdf = new HibernateDAOFactory(); 

    public abstract AirportDAO getAirlineDAO(); 

    public static DAOFactory getFactory() 
    { 
     //return a concrete implementation here, which implementation you 
     //return might depend on some application configuration settings. 
    } 
} 

public class HibernateDAOFactory extends DAOFactory 
{ 
    private static EntityManagerFactory emFactory = Persistence.createEntityManagerFactory("myPersistenceUnit"); 

    public static EntityManager getEM() 
    { 
     return emFactory.createEntityManager(); 
    } 

    public AirportDAO getAirportDAO() 
    { 
     return new HibernateAirportDAO(); 
    } 
} 

यह पैटर्न अपने HibernateDAOFactory एक भी ईएमएफ पकड़ और ईएमएस के साथ व्यक्तिगत डीएओ उदाहरणों की आपूर्ति करने की अनुमति देता है। यदि आप फेटरी मार्ग से नीचे नहीं जाना चाहते हैं तो स्प्रिंग निर्भरता इंजेक्शन के साथ आपके लिए डीएओ उदाहरणों को संभालने में बहुत अच्छा है।

संपादित करें: कुछ मान्यताओं को स्पष्ट करें।

+0

हां, लेकिन क्या यह व्यवसाय/सेवा और डेटा एक्सेस परतों का मिश्रण नहीं है? मैं विशेष रूप से getA BoxOperatingFrom() का मतलब है। या यह अच्छा अभ्यास है? यह इस क्षेत्र में मेरी पहली परियोजना है, इसलिए मुझे यकीन नहीं है कि –

+1

इस कारखाने के दृष्टिकोण को वसंत परिदृश्य में कोई समझ नहीं आता है। –

+0

@seanizer हाँ, वसंत के साथ ओपी शायद अपने डीएओ को अपने ऐप संदर्भ के हिस्से के रूप में कॉन्फ़िगर करना और उन्हें इंजेक्ट करना चाहता है। – Qwerky

5

यह article एडम बिएन द्वारा उपयोगी हो सकता है।

संबंधित मुद्दे