2011-11-13 11 views
12

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

+2

यह क्यों फर्क पड़ता है कि वर्ग एक इकाई है:

import org.springframework.data.repository.CrudRepository; import com.example.model.FluentEntity; public interface FluentEntityRepository extends CrudRepository<FluentEntity, Long> { } 

और यहाँ कुछ परीक्षण कर रहे हैं? कुछ और बनाने के लिए इसका उपयोग करने के लिए इकाइयों को बनाने के लिए बिल्डर पैटर्न का उपयोग क्यों कर रहा है? –

+0

मैं इसे डीबी में स्टोर करने में सक्षम होने के लिए एक इकाई बनना चाहता हूं। –

उत्तर

5

बेशक यह संभव है, तो आप सिर्फ हर इकाई के लिए एक (संभवतः नेस्ट) बिल्डर प्रदान करने के लिए है। (

FluentEntity entity = FluentEntity.builder().setSomeName(someName).setSomeNumber(someNumber) 
       .setSomeFlag(someFlag).build(); 

बस ध्यान आप प्राथमिक कुंजी की तरह स्वत: जनरेट की फील्ड छोड़ करने के लिए है कि में रखने में:

import javax.persistence.Entity; 
import javax.persistence.GeneratedValue; 
import javax.persistence.GenerationType; 
import javax.persistence.Id; 

@Entity 
public class FluentEntity { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private long id; 
    private String someName; 
    private int someNumber; 
    private boolean someFlag; 

    protected FluentEntity(){} 

    private FluentEntity(String someName, int someNumber, boolean someFlag) { 
     this.someName = someName; 
     this.someNumber = someNumber; 
     this.someFlag = someFlag; 
    } 

    public long getId() { 
     return id; 
    } 

    public String getSomeName() { 
     return someName; 
    } 

    public int getSomeNumber() { 
     return someNumber; 
    } 

    public boolean isSomeFlag() { 
     return someFlag; 
    } 

    public static FluentEntityBuilder builder() { 
     return new FluentEntityBuilder(); 
    } 

    public static class FluentEntityBuilder { 

     private String someName; 
     private int someNumber; 
     private boolean someFlag; 

     public FluentEntityBuilder setSomeName(final String someName) { 
      this.someName = someName; 
      return this; 
     } 

     public FluentEntityBuilder setSomeNumber(final int someNumber) { 
      this.someNumber = someNumber; 
      return this; 
     } 

     public FluentEntityBuilder setSomeFlag(final boolean someFlag) { 
      this.someFlag = someFlag; 
      return this; 
     } 

     public FluentEntity build() { 
      return new FluentEntity(someName, someNumber, someFlag); 
     } 

    } 

} 

उपयोग करने के लिए यह इस होगा कोड:

यहाँ एक काम कर उदाहरण है इस उदाहरण के मामले में id) यदि आपके पास कुछ है।

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

आप Project Lombok

फिर भी पर एक नज़र रखना चाहिए, यहाँ इस बिल्डर (स्प्रिंग बूट और हाइबरनेट के साथ लागू) परीक्षण करने के लिए कुछ कोड है।

भंडार:

import static org.hamcrest.CoreMatchers.is; 
import static org.hamcrest.CoreMatchers.notNullValue; 
import static org.hamcrest.MatcherAssert.assertThat; 
import static org.hamcrest.Matchers.greaterThan; 

import java.util.stream.StreamSupport; 

import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.boot.test.context.SpringBootTest; 
import org.springframework.test.context.junit4.SpringRunner; 
import org.springframework.transaction.annotation.Transactional; 

import com.example.model.FluentEntity; 

@RunWith(SpringRunner.class) 
@Transactional 
@SpringBootTest 
public class FluentEntityRepositoryTests { 

    @Autowired 
    private FluentEntityRepository fluentEntityRepository; 

    @Test 
    public void insertAndReceiveFluentEntityCreatedWithBuilder() { 
     final String someName = "name"; 
     final int someNumber = 1; 
     final boolean someFlag = true; 

     FluentEntity entity = FluentEntity.builder().setSomeName(someName).setSomeNumber(someNumber) 
       .setSomeFlag(someFlag).build(); 

     entity = fluentEntityRepository.save(entity); 
     assertThat("Entity did not get an generated Id!", entity.getId(), greaterThan(-1L)); 
     assertThat("Entity name did not match!", entity.getSomeName(), is(someName)); 
     assertThat("Entity number did not match!", entity.getSomeNumber(), is(someNumber)); 
     assertThat("Entity flag did not match!", entity.isSomeFlag(), is(someFlag)); 
    } 

    @Test 
    public void insertSomeAndReceiveFirst() { 
     fluentEntityRepository.save(FluentEntity.builder().setSomeName("A").setSomeNumber(1).setSomeFlag(true).build()); 
     fluentEntityRepository 
       .save(FluentEntity.builder().setSomeName("B").setSomeNumber(2).setSomeFlag(false).build()); 
     fluentEntityRepository.save(FluentEntity.builder().setSomeName("C").setSomeNumber(3).setSomeFlag(true).build()); 

     final Iterable<FluentEntity> findAll = fluentEntityRepository.findAll(); 
     assertThat("Should get some iterable!", findAll, notNullValue()); 

     final FluentEntity fluentEntity = StreamSupport.stream(findAll.spliterator(), false).findFirst().get(); 
     assertThat("Should get some entity!", fluentEntity, notNullValue()); 
    } 

} 
+0

जेपीए ढांचे के लिए ('@ Autowire'?)" स्वचालित रूप से "संस्थाओं केवल बिल्डर में setters है कि उदाहरण बना पाएगा? –

+1

मुझे नहीं पता कि मुझे आपका प्रश्न मिला है, लेकिन सामान्य रूप से फ़ील्ड एक्सेस का उपयोग होने पर सेटर्स की आवश्यकता नहीं होती है। फिर जेपीए प्रदाता सेटर्स का आह्वान नहीं करता है और बिल्डर्स आपके व्यावसायिक कोड के लिए पर्याप्त हो सकते हैं। http://download.oracle.com/otn-pub/jcp/persistence-2_1-fr-eval-spec/JavaPersistence.pdf –

+0

ठीक है, लेकिन मुख्य कारण मैं उपयोग करना चाहते हैं: "2.2 लगातार फ़ील्ड और गुण" में देखें एक निर्माता ऐसा है कि मैं फ़ील्ड 'अंतिम' बना सकता हूं। यदि आप फ़ील्ड एक्सेस का उपयोग करते हैं, तो आप उन्हें अंतिम नहीं बना सकते हैं? –