JPA

2011-11-13 16 views
12

ile varlıklar için Builder Kalıbı'nı nasıl kullanabilirsiniz? Çok sayıda parametreli bir sınıfa sahipken, oluşturucu desenini kullanmanın yararlı olduğunu okudum. Oluşturucu desenini kullanarak bir varlığı nasıl uygulayabileceğinizi merak ediyorum. Örnek kod sağlayabiliyorsanız harika olur.JPA

+2

Neden sınıf bir varlık olduğunu fark eder:

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

Ve burada bazı testler nelerdir? Başka bir şey oluşturmak için onu kullanmaktan farklı olan varlıkları oluşturmak için neden oluşturucu desenini kullanıyorsunuz? –

+0

Ben db saklamak için bir varlık olmasını istiyorum. –

cevap

5

Elbette, her varlık için bir (muhtemelen yuvalanmış) oluşturucu sağlamanız yeterlidir. içinde (

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

Sadece birincil anahtar gibi otomatik olarak oluşturulmuş alanlar hariç zorunda aklınızda bulundurun:

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

    } 

} 

bu olurdu kullanmak için kod: Burada

bir çalışma örneğidir Bu örnekte id) varsa.

Her Varlık için Oluşturucu sınıfları oluşturmak için "boilerplate" kodundan kurtulmak isterseniz, bir kitaplık lembok gibi bir kitaplık öneririm. Ardından, İşverenlerinizi (ve hatta daha fazlasını) yalnızca Girişimlerinize not ekleyerek alacaksınız, belki de id alanlarını hariç tutmak için biraz fazladan çalışma maliyeti.

Sen Yine Project Lombok

bakmak gerekir, burada (Bahar Boot ve hazırda ile uygulanan) bu Builder test etmek için bazı kodudur.

depo:

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

JPA çerçevesi "otomatik olarak" ("Autowire"?) Yapabilecekse, yalnızca oluşturucuda ayarlayıcıları olan Varlıklar örneğini oluşturur mu? –

+1

Sorunuzu alsam bilmiyorum ama genel olarak saha erişimi kullanılıyorsa ayarlayıcılara gerek yoktur. Daha sonra JPA sağlayıcısı setçileri çağırmaz ve inşaatçılar iş kodunuz için yeterli olabilir. "2.2 Kalıcı Alanlar ve Özellikler" konusuna bakın: http://download.oracle.com/otn-pub/jcp/persistence-2_1-fr-eval-spec/JavaPersistence.pdf –

+0

Tamam, ama kullanmak istediğim ana neden Bir inşaatçı, böylece alanları final yapabilirim. Saha erişimini kullanırsanız, onları nihai yapamazsınız, değil mi? –