2013-05-14 10 views
13

मैं कुछ ट्यूटोरियल पढ़ रहा है और मैं देख सकता था कि MVC कार्यान्वयनहाइबरनेट और स्प्रिंग - दाव, सेवाएं

के सबसे पर आधारित हैं:

1) उदाहरण के लिए एक दाव इंटरफ़ेस "IUserDao"

2) कि इंटरफ़ेस का एक दाव impl - "mySimpleUserDaoImpl"

3) दृढ़ता के लिए एक सेवा इंटरफ़ेस: "IUserService"

4) और एक impl - "यू serServiceImpl "

क्या यह सबसे अच्छा अभ्यास है? मेरा मतलब है कि मैं इस सवाल से पूछता हूं क्योंकि यह getXById(), deleteX (x), createX (x) विधियों के साथ 30 सेवाओं के लिए अनावश्यक प्रतीत होता है जो कम या ज्यादा कर रहे हैं।

कृपया खाता है कि मैं वसंत 3 उपयोग कर रहा हूँ में लेने के लिए और 4 हाइबरनेट, और मैंने तय कर लिया कि मैं इस प्रश्न को पूछने से पहले मैं

धन्यवाद कोड के साथ अपने कीबोर्ड बंद शुरू करते हैं।

+2

आप इंटरफेस के लिए 'I' उपसर्ग छोड़ सकते हैं। उपयोगकर्ता को यह पता नहीं होना चाहिए कि यह एक इंटरफ़ेस प्राप्त कर रहा है। बस उन्हें 'UserDAO' और' उपयोगकर्ता सेवा 'कहें। – Bart

+0

सहमत हैं, मैं इंटरफेस पर ड्रॉप। मैं व्यक्तिगत रूप से स्प्रिंग एनोटेशन के साथ इसे रखने के लिए अपने दाओ कक्षा रिपोजिटरीज को बुलाता हूं, लेकिन इससे कोई फर्क नहीं पड़ता। – bh5k

+1

तकनीक के लिए ट्यूटोरियल आमतौर पर व्यावसायिक तर्क से संबंधित नहीं हैं, इसलिए वे इसके लिए अच्छे संदर्भ नहीं हैं। एक समान प्रश्न है जो http://stackoverflow.com/q/3688664/217324 –

उत्तर

9

यदि आप अभी विकास शुरू कर रहे हैं, तो Spring JPA देखें। एक सेवा एक से कई रिपोजिटरीज (डीएओ) होना चाहिए। लेकिन मैं अब भी उस बॉयलरप्लेट कोड को हाथ से नहीं बनाऊंगा। वसंत जेपीए बुनियादी सीआरयूडी और खोज कार्यों के साथ-साथ पेजिनेशन को समाप्त करता है।

Here is a video जो वसंत, जेपीए, हाइबरनेट के लिए सभी कॉन्फ़िगरेशन के माध्यम से चलता है, और स्प्रिंग डेटा जेपीए के साथ समाप्त होता है जो आपको समाप्त होने वाले बॉयलरप्लेट कोड को दिखाता है।

<jpa:repositories base-package="com.mysampleapp.repository"/> 

बॉयलरप्लेट कोड के सभी अब नियंत्रित किया जाता है: स्प्रिंग डाटा जेपीए उपयोग करने के लिए

package com.mysampleapp.repository; 
import org.springframework.data.jpa.repository.JpaRepository; 
import org.springframework.stereotype.Repository; 
import com.wcfgroup.model.Employee; 

@Repository("employeeRepository") 
public interface EmployeeRepository extends JpaRepository<Employee, Long> { 
    Employee findBySsn(String ssn); 
} 

और फिर एक्सएमएल विन्यास:

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

+1

सेवा परत के बारे में ध्यान देने योग्य एक और बात यह है कि आपका @ ट्रांज़ेक्शन शुरू होना चाहिए।इसलिए यदि आप कई रिपॉजिटरीज़ में एक लेनदेन को रोलबैक करना चाहते हैं तो सेवा स्तर वह है जहां आप इसे करते हैं। यही कारण है कि सेवा Repositories के साथ एक से कई होना चाहिए। – bh5k

1

कोई भी 30 सेवा परतें या 30 दाओ परतों की आवश्यकता नहीं है। आपको उन इकाइयों को निर्दिष्ट करना चाहिए जो इकाई के अनुसार नहीं बल्कि व्यापार कार्यक्षमता के अनुसार विचार कर रहे हैं। कुछ कार्य के लिए 5 या 6 इकाइयां प्रासंगिक हो सकती हैं और उनको होना चाहिए एक परत में। लेकिन फिर भी आपको आवश्यकतानुसार उन अनावश्यक परतों में getXById(), deleteX (x), createX (x) प्राप्त करना होगा।

4

यह आवश्यक है कि प्रत्येक मॉडल के लिए दाओ, दाओआईएमएल, सेवा, सेवा इंपल हो।

  • UserDao
  • UserDaoImpl
  • UserService
  • UserServiceImpl

आप anf inteface EntityDao एक सामान्य वर्ग EntityDaoImpl, इस तरह उपयोग कर सकते हैं:

EntityDao:

public interface EntityDao<E> { 

void persist(E e) throws Exception; 

void remove(Object id) throws Exception; 

E findById(Object id) throws Exception; 
} 

EntityDaoImpl:

public class EntityDaoImpl<E> implements EntityDao<E> { 

@PersistenceContext(unitName="UnitPersistenceName") 
protected EntityManager entityManager; 

protected E instance; 
private Class<E> entityClass; 

@Transactional 
public void persist(E e) throws HibernateException{  
    getEntityManager().persist(e); 
} 
    @Transactional 
public void remove(Object id) throws Exception{  
    getEntityManager().remove((E)getEntityManager().find(getEntityClass(), id)); 
} 

public E findById(Object id) throws Exception {  
    return (E)getEntityManager().find(getEntityClass(), id);  
} 
    public EntityManager getEntityManager() { 
    return entityManager; 
} 
public void setEntityManager(EntityManager entityManager) throws Exception{ 
    this.entityManager = entityManager; 
} 

    public Class<E> getEntityClass() throws Exception{  
    if (entityClass == null) { 
      Type type = getClass().getGenericSuperclass(); 
      if (type instanceof ParameterizedType) 
      { 
       ParameterizedType paramType = (ParameterizedType) type; 
       if (paramType.getActualTypeArguments().length == 2) { 
        if (paramType.getActualTypeArguments()[1] instanceof TypeVariable) { 
         throw new IllegalArgumentException(
          "Can't find class using reflection"); 
        } 
        else { 
         entityClass = (Class<E>) paramType.getActualTypeArguments()[1]; 
        } 
       } else { 
        entityClass = (Class<E>) paramType.getActualTypeArguments()[0]; 
       } 
      } else { 
       throw new Exception("Can't find class using reflection"); 
      } 
     } 
     return entityClass; 
    } 
} 

और तुम इस तरह उपयोग कर सकते हैं:

public interface UserDao extends EntityDao<User> { 

} 

और

public class UserDaoImpl extends EntityDaoImpl<User> implements UserDao{ 

} 
+0

यह सब कोड अनिवार्य रूप से स्प्रिंग डेटा जेपीए आपको प्रदान करता है: http://www.springsource.org/spring-data/jpa – bh5k

+1

वास्तव में इस कोड के साथ कुछ त्रुटियां हैं, आप अपने लेनदेन को शुरू नहीं करना चाहते हैं डीएओ/रिपोजिटरी स्तर। – bh5k

1

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

यदि आपके पास पूरी तरह से सीआरयूडी एप्लीकेशन है तो आप कानूनी रूप से सेवाओं के बिना कर सकते हैं, डीएओ पर @ ट्रांसेक्शनल डाल सकते हैं, और नियंत्रक से डीएओ को कॉल कर सकते हैं। यदि सेवा अपना वजन खींच नहीं रही है तो इससे छुटकारा पाएं।

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

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

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