java - डीएओ और सर्विस लेयर(जेपीए/हाइबरनेट+स्प्रिंग)




spring architecture (4)

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

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

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

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

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

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

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

यदि आप अपनी सेवा में अपने इकाई प्रबंधक का उपयोग करने जा रहे हैं, तो इकाई प्रबंधक को अपने डीएओ के रूप में सोचें, क्योंकि यह वही है जो यह है। यदि आपको कुछ अनावश्यक क्वेरी बिल्डिंग को हटाने की आवश्यकता है, तो अपनी सेवा कक्षा में ऐसा न करें, इसे उस वर्ग में निकालें जो इकाई प्रबंधक का उपयोग करता है और इसे आपके डीएओ बनाता है। यदि आपका उपयोग केस वास्तव में सरल है, तो आप पूरी तरह से सर्विस लेयर को छोड़ सकते हैं और अपने getAirplaneById() मैनेजर या डीएओ को कंट्रोलर्स में इस्तेमाल कर सकते हैं क्योंकि आपकी सारी सेवा करने जा रही है, डीएओ के 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...
   }
}

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

एक ऑब्जेक्ट जो किसी प्रकार के डेटाबेस या दृढ़ता तंत्र को एक अमूर्त इंटरफ़ेस प्रदान करता है, डेटाबेस के ब्योरे को उजागर किए बिना कुछ विशिष्ट संचालन प्रदान करता है।

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


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

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

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

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


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

सरल उदाहरण:

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();

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

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

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

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







dao