加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 如何使用具有JPA的实体的Builder Pattern

发布时间:2020-12-14 05:25:19 所属栏目:Java 来源:网络整理
导读:我读到,当你有一个有很多参数的类时,使用构建器模式是很有用的.我想知道如何使用构建器模式实现一个实体.如果您可以提供示例代码将是很棒的. 解决方法 当然这是可能的,你只需要为每个实体提供一个(可能是嵌套的)Builder. 这是一个工作示例: import javax.pe
我读到,当你有一个有很多参数的类时,使用构建器模式是很有用的.我想知道如何使用构建器模式实现一个实体.如果您可以提供示例代码将是很棒的.

解决方法

当然这是可能的,你只需要为每个实体提供一个(可能是嵌套的)Builder.

这是一个工作示例:

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

    }

}

使用它的代码是这样的:

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

请记住,如果你有一些,你必须排除自动生成的字段,如主键(在这个例子中为id).

如果你想摆脱为每个实体创建Builder类的“样板”代码,我会推荐一个便利库,像lombok.然后,您将通过注释您的Entites获得您的Builders(甚至更多),或许要花费一些额外的工作来排除id字段.

你应该看看Project Lombok

不过,这里有一些代码来测试这个Builder(使用Spring Boot和Hibernate实现).

存储库:

import org.springframework.data.repository.CrudRepository;

import com.example.model.FluentEntity;

public interface FluentEntityRepository extends CrudRepository<FluentEntity,Long> {

}

这里有一些测试:

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

}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读