2013-02-27 22 views
35

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

प्रदर्शित करने के लिए, मैं आमतौर पर कोड लिखने के रूप में:

@Transactional(readOnly = true) 
public List<UserDTO> getAllUserAsUserDTO() { 
    List<UserDTO> userDTOs = new ArrayList<UserDTO>(); 

    for(User user : getAllUser()) { 
     userDTOs.add(constructUserDTO(user)); 
    } 

    return userDTOs; 
} 

private UserDTO constructUserDTO(User user) { 
    UserDTO userDTO = new UserDTO(); 
    userDTO.setFullName(user.getFullName()); 
    userDTO.setId(user.getId()); 
    userDTO.setUsername(user.getUsername()); 
    userDTO.setRole(user.getRole()); 
    userDTO.setActive(user.isActive()); 
    userDTO.setActiveText(user.isActive() ? "Active" : "Inactive"); 
    return userDTO; 
} 
यहाँ

उपयोगकर्ता डेटाबेस इकाई है:

@javax.persistence.Entity 
@Table(name = "USER") 
public class User extends Entity { 

    @Transient 
    private static final long serialVersionUID = -112950002831333869L; 

    private String username; 
    private String fullName; 
    private boolean active; 
    private String role; 
    // other fields 

    public User() { 
     super(); 
    } 

    @NaturalId 
    @Column(name = "USERNAME", nullable = false) 
    public String getUsername() { 
     return username; 
    } 

    public void setUsername(String username) { 
     this.username = username; 
    } 

    @Column(name = "FULL_NAME") 
    public String getFullName() { 
     return fullName; 
    } 

    public void setFullName(String fullName) { 
     this.fullName = fullName; 
    } 

    @Column(name = "ACTIVE", nullable = false) 
    public boolean isActive() { 
     return active; 
    } 

    public void setActive(boolean active) { 
     this.active = active; 
    } 

    @Column(name = "ROLE") 
    public String getRole() { 
     return role; 
    } 

    public void setRole(String role) { 
     this.role = role; 
    } 
} 

और यह UserDTO है:

public class UserDTO extends BaseDTO { 

    private static final long serialVersionUID = -3719463614753533782L; 

    private String username; 
    private String fullName; 
    private String role; 
    private String activeText; 
    private Boolean active; 
    //other properties 

    public UserDTO() { 
     super(); 
    } 

    public String getUsername() { 
     return username; 
    } 

    public void setUsername(String username) { 
     this.username = username; 
    } 

    public String getFullName() { 
     return fullName; 
    } 

    public void setFullName(String fullName) { 
     this.fullName = fullName; 
    } 

    public String getRole() { 
     return role; 
    } 

    public void setRole(String role) { 
     this.role = role; 
    } 

    public String getActiveText() { 
     return activeText; 
    } 

    public void setActiveText(String activeText) { 
     this.activeText = activeText; 
    } 

    public Boolean getActive() { 
     return active; 
    } 

    public void setActive(Boolean active) { 
     this.active = active; 
    } 
} 

तो मैं सोच रहा था कि क्या यह दो वस्तुओं के बीच गुणों की प्रतिलिपि बनाने का एकमात्र तरीका है। मुझे लगता है मुझे यकीन नहीं है। इसके अलावा मैं lambdaj का उपयोग कर रहा हूं, तो क्या इस एपीआई में कोई तरीका है जिसके द्वारा मैं इन सभी गुणों को अन्य ऑब्जेक्ट्स की सूची बनाने के लिए कॉपी कर सकता हूं?

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

+0

की संभावित डुप्लिकेट (https://stackoverflow.com/questions/1432764/any-tool- के लिए जावा-ऑब्जेक्ट-टू-ऑब्जेक्ट-मैपिंग) – tkruse

उत्तर

19

आप dozer पर एक नज़र जो एक

जावा बीन जावा के लिए बीन नक्शाकार है हो सकता है रिकर्सिवली प्रतियां एक वस्तु से दूसरे करने के लिए डेटा। आम तौर पर, ये जावा बीन्स विभिन्न जटिल प्रकारों के होंगे।

Another better link...

2

आप प्रतिबिंब का उपयोग कर सकते वस्तुओं अपने डीएओ में सभी get तरीकों को खोजने और डीटीओ में बराबर set विधि कॉल करने के। यह केवल तभी काम करेगा यदि ऐसी सभी विधियां मौजूद हों। इसके लिए उदाहरण कोड ढूंढना आसान होना चाहिए।

22

आप Apache Commmons Beanutils उपयोग कर सकते हैं। एपीआई

org.apache.commons.beanutils.PropertyUtilsBean.copyProperties(Object dest, Object orig) है।

यह सभी मामलों के लिए "मूल" बीन से "गंतव्य" बीन से संपत्ति मूल्यों की प्रतिलिपि बनाता है जहां संपत्ति के नाम समान हैं।

अब मैं विषय से बाहर जा रहा हूं। डीटीओ का उपयोग ज्यादातर ईजेबी 3 में एक विरोधी पैटर्न माना जाता है। यदि आपके डीटीओ और आपकी डोमेन ऑब्जेक्ट्स बहुत समान हैं, तो कोड को डुप्लिकेट करने की वास्तव में कोई आवश्यकता नहीं है। डीटीओ में अभी भी योग्यता है, खासकर नेटवर्क बैंडविड्थ को बचाने के लिए जब रिमोट एक्सेस शामिल है। मेरे पास आपके एप्लिकेशन आर्किटेक्चर के बारे में विवरण नहीं है, लेकिन यदि आपके द्वारा लिखे गए परतों में तार्किक परतें हैं और नेटवर्क पार नहीं करती हैं, तो मुझे डीटीओ की आवश्यकता नहीं दिखाई देती है।

+14

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

+0

यह एक अच्छा सुझाव है। लेकिन क्या होगा यदि डीटीओ में केवल 4 गुण हैं और वास्तविक वस्तु में 50 गुण हैं। मेरा मामला, जब मैं यहां उल्लिखित प्रतिलिपि का उपयोग करता हूं, तो यह वास्तविक वस्तु द्वारा केवल गुणों के साथ ओवरराइट करता है। शेष 46 गुण शून्य हो जाते हैं। क्या यह व्यवहार करने की उम्मीद है? – HopeKing

2

क्या lambdaj का project function नहीं है जो आप खोज रहे हैं?

यह कुछ इस तरह दिखाई देंगे:

List<UserDTO> userNDtos = project(users, UserDTO.class, on(User.class).getUserName(), on(User.class).getFullName(), .....); 

(तदनुसार UserDTO के लिए निर्माता निर्धारित करें ...)

भी उदाहरण के लिए here देखें ...

4

मैं एक आवेदन है कि मैं डीटीओ को एक JPA संस्था से बदलने की जरूरत थी, और मुझे इसके बारे में सोचा और अंत में सरल गुण और भी कॉपी करने के लिए org.springframework.beans.BeanUtils.copyProperties का उपयोग कर आया जटिल गुणों को बदलने के लिए org.springframework.binding.convert.service.DefaultConversionService का विस्तार और उपयोग करना।

विस्तार में मेरी सेवा कुछ इस तरह था: [? जावा वस्तु मानचित्रण आपत्ति उठाने के लिए किसी भी उपकरण]

@Service("seedingConverterService") 
public class SeedingConverterService extends DefaultConversionService implements ISeedingConverterService { 
    @PostConstruct 
    public void init(){ 
     Converter<Feature,FeatureDTO> featureConverter = new Converter<Feature, FeatureDTO>() { 

      @Override 
      public FeatureDTO convert(Feature f) { 
       FeatureDTO dto = new FeatureDTO(); 
       //BeanUtils.copyProperties(f, dto,"configurationModel"); 
       BeanUtils.copyProperties(f, dto); 
       dto.setConfigurationModelId(f.getConfigurationModel()==null?null:f.getConfigurationModel().getId()); 
       return dto; 
      } 
     }; 

     Converter<ConfigurationModel,ConfigurationModelDTO> configurationModelConverter = new Converter<ConfigurationModel,ConfigurationModelDTO>() { 
      @Override 
      public ConfigurationModelDTO convert(ConfigurationModel c) { 
       ConfigurationModelDTO dto = new ConfigurationModelDTO(); 
       //BeanUtils.copyProperties(c, dto, "features"); 
       BeanUtils.copyProperties(c, dto); 
       dto.setAlgorithmId(c.getAlgorithm()==null?null:c.getAlgorithm().getId()); 
       List<FeatureDTO> l = c.getFeatures().stream().map(f->featureConverter.convert(f)).collect(Collectors.toList()); 
       dto.setFeatures(l); 
       return dto; 
      } 
     }; 
     addConverter(featureConverter); 
     addConverter(configurationModelConverter); 
    } 
} 
संबंधित मुद्दे

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