Uma API REST com 봄

61670 단어
예술은 주황색의 천재 프로젝트를 완성하는 데 도움을 줄 수 있는 예술이다.
예술 형식에 관한 글로, estilo 블로그에 실린 sobre um projeto em Spring.
O passo a passo foi implementado e O código estáaqui:lottery-orange-talents

Contexto


로트리아 체계를 토대로 우리는 새로운 에너지 이용 방식이 필요하다.
API deverágerar n 분쿠메로스 aleat órios para A aposta do requestante 하나, cada n 분쿠메로 deveestar association 하나, 이메일para A pessoa que est áconcorrendo 하나.
Essencialmente s ão 2 endpoints, 음 receberáo e-mail da pessoa e returnara áum objeto de resposta comos n 분쿠메로스 sortados para a aposta e o outro endpoints, criaã o todas를 Soliciante(passando seu e-mail como par –metro)로 개발했다.
Spring + Hibernate를 구현한 실용적인 Java como ecossistema

샌안토니오


모델 전략


API REST, 어플리케이션 요구사항, 중요 문서 및 시스템 모델을 구현하고 클래스, 관계 등으로 설명합니다.
Nesse contexto,irei Utizar modelagem de dados UML mesclando modelagem Confitual com modelagem lógica.
자부심 = 실체를 범례와 기술에 독립된 시스템으로 묘사한다.
요기카= 실체, 관계, 결정과 범례, 관계 등으로 묘사한다.

Gerando a aplicaçço 스프링 부츠


프로젝트에서 irei utilizar o Spring은 com을 세그먼트 구성으로 초기화합니다.
  • Maven como gerenciador de Dependeências;
  • Versão 2.4.2 do Spring;
  • 자바11;
  • Spring Web에 의존하는 MVC 어플리케이션, 보조 컨트롤러, 서비스 등의 어플리케이션
    오, 짐.xml inicial ficaráassim:
    <parent>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-parent</artifactId>
      <version>2.4.2</version>
      <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.armandotdelcol</groupId>
    <artifactId>lottery-api</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>lottery-api</name>
    <description>Desafio Orange Talents</description>
    <properties>
      <java.version>11</java.version>
    </properties>
    <dependencies>
      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
      </dependency>
    </dependencies>
    
    <build>
      <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
      </plugins>
    </build>
    

    파드로 카마다스


    데이터 수집 시스템에서 데이터 수집 시스템을 사용하여 데이터 수집 시스템의 데이터 수집 시스템, 데이터 수집 시스템의 데이터 수집 시스템, 데이터 수집 시스템의 데이터 수집 시스템, 데이터 수집 시스템의 데이터 수집 시스템, 데이터 수집 시스템의 데이터 수집 시스템, 데이터 수집 시스템의 데이터 수집 시스템, 데이터 수집 시스템의 데이터 수집 시스템, 데이터 수집 시스템의 데이터 수집 시스템과 데이터 수집 시스템의 데이터 수집 시스템을 실현한다.

    Criando를 실체로


    Criarei는 실체로서 pacote 실체가 없고, começando pela entidade 복권.
    모든 상업 모델에 상업은행이 없기 때문에 irei precisar adicionar uma forma do projeto Spring fazer o mapeamento는 상업은행과 상업은행에 전문적인 상업 모델을 제공한다.
    Java 영구화 Api(Java Persistence Api)의 특수한 실현에서 우리는 일련의 Java 응용 프로그램을 정의했다
    봄의 생태 조수가 겨울잠을 간단하게 이용하는 것이 아니라 전문적인 ira fazer에 의존해 실용 프로그램을 다운로드하는 것이 의존이다.
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    
    Essa Dependent encia는 JPA API를 포함하여 JPA com Hibernate como default, JDBC e outras bibliotecas Necesárias를 구현합니다.
    데이터 은행의 토대 위에서 우리는 새로운 데이터 은행을 개발하여 데이터 은행의 집행 속도를 확보하고 데이터 은행의'전문적인'운영 효율을 확보했다.
    H2에서 이것은pom이 필요하지 않은 의존이다.xml:
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <scope>runtime</scope>
    </dependency>
    

    복권.


    @Entity
    @Table(name = "tb_lottery_tickets")
    public class LotteryTicket implements Serializable {
    
        private static final long serialVersionUID = 1L;
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
    
        @Column(nullable = false)
        private Integer bet1;
    
        @Column(nullable = false)
        private Integer bet2;
    
        @Column(nullable = false)
        private Integer bet3;
    
        @Column(nullable = false)
        private Integer bet4;
    
        @Column(columnDefinition = "TIMESTAMP WITHOUT TIME ZONE")
        private Instant createdAt;
    
        public LotteryTicket() {
        }
    
        public LotteryTicket(Long id, Integer bet1, Integer bet2, Integer bet3, Integer bet4) {
            this.id = id;
            this.bet1 = bet1;
            this.bet2 = bet2;
            this.bet3 = bet3;
            this.bet4 = bet4;
        }
    
        // OMITIDO AQUI OS GETTERS AND SETTERS DE id, bet1, bet2, bet3 e bet4.
    
        public Instant getCreatedAt() {
            return createdAt;
        }
    
        @PrePersist
        public void prePersist() {
            createdAt = Instant.now();
        }
    
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            LotteryTicket that = (LotteryTicket) o;
            return Objects.equals(id, that.id);
        }
    
        @Override
        public int hashCode() {
            return Objects.hash(id);
        }
    }
    
    엔티티에는 엔티티를, 엔티티에는 카테고리를, 테이블에는 사용자 정의 이름을 사용합니다.
    e@GeneratedValue para definir a chave primaria autoincrementavél,@Column para utilizar o nullable=false e não aceitar valores nulos...
    실용적이고 즉각적이며 명확한 시간대를 만들고 실용적이고 임시적이며 임시적이며 임시적이며 임시적이며 임시적이며 임시적이며 임시적이며 임시적이며 임시적이며 임시적이다.

    노름꾼


    @Entity
    @Table(name = "tb_bettors")
    public class Bettor implements Serializable {
    
        private static final long serialVersionUID = 1L;
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
    
        @Column(nullable = false)
        private String email;
    
        public Bettor() {
        }
    
        public Bettor(Long id, String email) {
            this.id = id;
            this.email = email;
        }
    
        // OMITINDO GETTERS AND SETTERS E HASHCODE E EQUALS
    }
    

    컨소시엄


    한 장의 복권, 한 장의 베팅자의 참고표, 한 장의 베팅자의 참고표, 한 장의 베팅자의 참고표, 한 장의 베팅자의 참고표, 한 장의 베팅자의 참고표, 한 장의 베팅자의 참고표, 한 장의 베팅자의 참고표, 한 장의 베팅자의 참고표, 한 장의 베팅자의 참고표
    @ManyToOne
    @JoinColumn(name = "bettor_id", nullable = false)
    private Bettor bettor;
    
    Adicionando os devidos getter and Setters e colocando para instanciar via construtor também junto aos demais atributos.
    Jáem Bettor adicionei a anotaão@OneToMany com a opão Mapped by Conference do campo na tabela de tickets:
    @OneToMany(mappedBy="bettor")
    private Set<LotteryTicket> lotteryTickets;
    
    아주 좋은 조합, 아주 좋은 조합, 아주 좋은 복권...

    내부 통신 확인


    우리는 능력 있는 사람, 능력 있는 사람, 능력 있는 사람, 능력 있는 사람, 능력 있는 사람, 능력 있는 사람, 능력 있는 사람, 능력 있는 사람, 능력 있는 사람, 능력 있는 사람, 능력 있는 사람, 능력 있는 사람, 능력 있는 사람...
    Primeiro irei criar um perfil de tests emsrc/main/resources chamado 애플리케이션 테스트.부동산 회사:
    spring.datasource.url=jdbc:h2:mem:testdb
    spring.datasource.username=sa
    spring.datasource.password=
    
    spring.h2.console.enabled=true
    spring.h2.console.path=/h2-console
    
    e 무arquivo 신청.속성:
    spring.profiles.active=test
    
    spring.jpa.open-in-view=false
    
    테스트에서 Tivando o perfil은 Caso serço nosso 컨트롤러가 아닌 BD serço feitas fechadas Deidas 서비스 라이브러리의 거래로 정의했습니다.
    인터페이스로서 우리는 JPA에 새로운 응용 프로그램을 제공하여 국제 상업은행과 일본 은행 사이에 다음과 같은 기능을 실현할 수 있도록 해야 한다.
    @Repository
    public interface LotteryTicketRepository extends JpaRepository<LotteryTicket, Long> {
    }
    
    // E
    
    @Repository
    public interface BettorRepository extends JpaRepository<Bettor, Long> {
    }
    
    Dados은행의 내부 테스트에서 우리의 테스트 결과는 다음과 같다.
    public static void main(String[] args) {
    
        ApplicationContext applicationContext = new SpringApplicationBuilder(LotteryApiApplication.class)
                .web(WebApplicationType.SERVLET)
                .run(args);
    
        BettorRepository bettorRepository = applicationContext.getBean(BettorRepository.class);
        LotteryTicketRepository lotteryTicketRepository = applicationContext.getBean(LotteryTicketRepository.class);
    
        Bettor bettor1 = new Bettor();
        bettor1.setEmail("[email protected]");
        bettorRepository.save(bettor1);
    
        Random betGenerator = new Random();
        LotteryTicket lotteryTicket1 = new LotteryTicket();
        lotteryTicket1.setBet1(betGenerator.nextInt(100));
        lotteryTicket1.setBet2(betGenerator.nextInt(100));
        lotteryTicket1.setBet3(betGenerator.nextInt(100));
        lotteryTicket1.setBet4(betGenerator.nextInt(100));
        lotteryTicket1.setBettor(bettor1);
        lotteryTicketRepository.save(lotteryTicket1);
    }
    
    aplica to startada e acessando URL 하나. cria dos registrose confirmar que a intera que o banco de dados estáok 검증에 사용됩니다.아그라 와모스(Agora vamos)는 오틀라스 카마다스(outras camadas)의 집행자다.

    Dto


    마스터 및 서비스 룸의 임시 채널에 벽면을 설치하고 테이블에 설치합니다.
    public class LotteryTicketDTO implements Serializable {
    
        private static final long serialVersionUID = 1L;
    
        private Long id;
        private Integer bet1;
        private Integer bet2;
        private Integer bet3;
        private Integer bet4;
        private Bettor bettor;
    
        public LotteryTicketDTO() {
        }
    
        public LotteryTicketDTO(Long id, Integer bet1, Integer bet2, Integer bet3, Integer bet4, Bettor bettor) {
            this.id = id;
            this.bet1 = bet1;
            this.bet2 = bet2;
            this.bet3 = bet3;
            this.bet4 = bet4;
            this.bettor = bettor;
        }
    
        public LotteryTicketDTO(LotteryTicket entity) {
            this.id = entity.getId();
            this.bet1 = entity.getBet1();
            this.bet2 = entity.getBet2();
            this.bet3 = entity.getBet3();
            this.bet4 = entity.getBet4();
            this.bettor = entity.getBettor();
        }
    
        // OMITINDO OS GETTERS AND SETTERS
    }
    

    서비스


    Na camada는 대중에게 서비스를 제공하고 새로운 정보를 이메일로 제공합니다.
    Precisarei usar os dois repositories jácriados,por isso irei usar o recurso de injeão de dependenceèncias do Spring com a anotaão@Autowired que jácuida de tudo pra mim e disponiliza os preciso.
    메모 없음, 이메일 없음, 이메일 없음, 이메일 없음, 이메일 없음, 이메일 없음 등의 메시지를 메시지에 삽입하십시오.
    @Repository
    public interface BettorRepository extends JpaRepository<Bettor, Long> {
    
      @Query("SELECT b FROM Bettor b WHERE b.email=:email")
      public Optional<Bettor> findByEmail(@Param("email") String email);
    
    }
    
    에세노보 메토도findByEmail에는 기본 JPA 구현 시나리오가 존재하지 않는 것이 올바른 선택이다.
    Minha classe LotteryTicketService ficou assim:
    @Transactional
    public LotteryTicketDTO insert(LotteryTicketDTO dto) {
        Random betGenerator = new Random();
        Bettor bettor = getOrCreateBettor(dto.getBettor().getEmail());
        LotteryTicket entity = new LotteryTicket();
        entity.setBet1(betGenerator.nextInt(100));
        entity.setBet2(betGenerator.nextInt(100));
        entity.setBet3(betGenerator.nextInt(100));
        entity.setBet4(betGenerator.nextInt(100));
        entity.setBettor(bettor);
        entity = lotteryTicketRepository.save(entity);
        return new LotteryTicketDTO(entity);
    }
    
    @Transactional
    public List<LotteryTicketDTO> findAllByEmail(LotteryTicketDTO dto) {
        Optional<Bettor> obj = bettorRepository.findByEmail(dto.getBettor().getEmail());
        Set<LotteryTicket> lotteryTickets = obj.get().getLotteryTickets();
        List<LotteryTicketDTO> dtoList = lotteryTickets.stream().map(x -> new LotteryTicketDTO(x)).collect(Collectors.toList());
        return dtoList;
    }
    
    @Transactional
    private Bettor getOrCreateBettor(String email) {
        Optional<Bettor> obj = bettorRepository.findByEmail(email);
        try {
            return obj.get();
        } catch (Exception e) {
            Bettor bettor = new Bettor();
            bettor.setEmail(email);
            return bettorRepository.save(bettor);
        }
      }
    
    봄에 우리는 대서양을 횡단하는 지역에서 거래를 할 수 있다는 새로운 거래 지표가 나왔다.
    OmétodogetOrCreateBettor는 베팅자에게 이메일을 보내 새로운 베팅자와 베팅자 간의 관계를 재확인했다.

    컨트롤러


    부동산 서비스 센터의 고객 컨트롤러:
    @RestController
    @RequestMapping(value = "/lottery_tickets")
    public class LotteryTicketsController {
    
      @Autowired
      private LotteryTicketService lotteryTicketService;
    
      @GetMapping
      public ResponseEntity<List<LotteryTicketDTO>> findAllByEmail(@RequestBody LotteryTicketDTO dto) {
          List<LotteryTicketDTO> dtoList = lotteryTicketService.findAllByEmail(dto);
          return ResponseEntity.ok(dtoList);
      }
    
      @PostMapping
      public ResponseEntity<LotteryTicketDTO> insert(@RequestBody LotteryTicketDTO dto) {
          dto = lotteryTicketService.insert(dto);
          return ResponseEntity.ok().body(dto);
      }
    
    }
    
    anotaço@RestController garante que minha classe seja um controlador REST e@Resquest Mapping permite que eu 맞춤형rota de acesso pela URI
    Injeto o LotteryTicketService e crio dois métodos um POST para fazer a inserço de uma nova aposta e um GET para listar as apostas por email.
    우리의 복권 발행인과 베팅자 간의 관계, 베팅자와 베팅자 간의 관계, 베팅자와 베팅자 간의 관계, 베팅자와 베팅자 간의 관계 등등. 문제를 해결한 사람은 아디시오네 아노니올 아노니올 아노니올 아노니올 아노니올, 베팅자가 없는 복권 발행인:
    @JsonIgnore
    @OneToMany(mappedBy="bettor")
    @OrderBy("createdAt DESC")
    private Set<LotteryTicket> lotteryTickets;
    
    재무 테스트의 일부로서 우리는 고객의 요구를 충족시킬 새로운 소프트웨어가 필요하다.http://localhost:8080/lottery_tickets :
    JSON 본문:
    {
        "bettor": {
            "email": "[email protected]"
        }
    }
    
    Resposta:
    {
      "id": 5,
      "bet1": 44,
      "bet2": 86,
      "bet3": 68,
      "bet4": 72,
      "bettor": {
        "id": 1,
        "email": "[email protected]"
      }
    }
    
    응, 획득:http://localhost:8080/lottery_tickets :
    JSON 본문
    {
        "bettor": {
            "email": "[email protected]"
        }
    }
    
    Resposta:
    [
      {
        "id": 5,
        "bet1": 44,
        "bet2": 86,
        "bet3": 68,
        "bet4": 72,
        "bettor": {
          "id": 1,
          "email": "[email protected]"
        }
      },
      {
        "id": 4,
        "bet1": 13,
        "bet2": 62,
        "bet3": 78,
        "bet4": 1,
        "bettor": {
          "id": 1,
          "email": "[email protected]"
        }
      }
    ]
    
    Java com Spring+Hibernate를 토대로 Loteria 시스템(bem simplório)의 실현을 보조했다.

    초과의


    엑세스 식당


    métodofindAllByEmail 없이 다양한 오류 정보를 제공할 수 있으며, 상태 500 caso o email informado n ã o possua nenhum cadastro como Bettor.파라타 이소 크리이 우마는 예외적으로 파코트가 없다services.exceptions:
    public class ResourceNotFoundException extends RuntimeException{
      public ResourceNotFoundException(String message) {
          super(message);
      }
    }
    
    모디피크오 메토도 파라투라 에로 에사 에소 대장:
    @Transactional
    public List<LotteryTicketDTO> findAllByEmail(LotteryTicketDTO dto) {
        Optional<Bettor> obj = bettorRepository.findByEmail(dto.getBettor().getEmail());
        Set<LotteryTicket> lotteryTickets = obj.orElseThrow(() -> new ResourceNotFoundException("Entity not found.")).getLotteryTickets();
        List<LotteryTicketDTO> dtoList = lotteryTickets.stream().map(x -> new LotteryTicketDTO(x)).collect(Collectors.toList());
        return dtoList;
    }
    
    표준 오류controllers.exceptions:
    public class StandardError implements Serializable {
    
        private static final long serialVersionUID = 1L;
    
        private Instant timestamp;
        private Integer status;
        private String error;
        private String message;
        private String path;
    
        public StandardError() {
        }
    
        // OMITINDO GETTERS AND SETTERS
    
    }
    
    처리 프로그램의 수준이 다르고 처리 오류의 수량과 자원이 일치하지 않습니다.
    @ControllerAdvice
    public class ResourceExceptionHandler {
      @ExceptionHandler(ResourceNotFoundException.class)
      public ResponseEntity<StandardError> entityNotFound(ResourceNotFoundException exception, HttpServletRequest request) {
          HttpStatus status = HttpStatus.NOT_FOUND;
          StandardError error = new StandardError();
          error.setTimestamp(Instant.now());
          error.setStatus(status.value());
          error.setError("Resource Not Found");
          error.setMessage(exception.getMessage());
          error.setPath(request.getRequestURI());
    
          return ResponseEntity.status(status).body(error);
      }
    }
    
    anota @Controller Advice coloca essa classe de erro sob comando do Spring e irádiffer Automatic Camente assim que Resource Notfounder Ocorr라는 프로젝트

    반복성 검사


    저희는 귀하께 복권 서비스를 제공하고 귀하께 복권 유럽 검증 서비스를 제공하여 귀하의 복권 품질을 확보할 것입니다.
    @Transactional
    private void generateBets(Bettor bettor, LotteryTicket entity) {
        Boolean allRight = false;
        Random betGenerator = new Random();
        Integer attempedBet1 = betGenerator.nextInt(100);
        Integer attempedBet2 = betGenerator.nextInt(100);
        Integer attempedBet3 = betGenerator.nextInt(100);
        Integer attempedBet4 = betGenerator.nextInt(100);
        Optional<Bettor> obj = bettorRepository.findByEmail(bettor.getEmail());
        Set<LotteryTicket> lotteryTickets = obj.get().getLotteryTickets();
        try {
            for (LotteryTicket lotteryTicket : lotteryTickets) {
                List<Integer> bets = new ArrayList<>();
                bets.add(lotteryTicket.getBet1());
                bets.add(lotteryTicket.getBet2());
                bets.add(lotteryTicket.getBet3());
                bets.add(lotteryTicket.getBet4());
                if (!bets.contains(attempedBet1) &&
                        !bets.contains(attempedBet2) &&
                        !bets.contains(attempedBet3) &&
                        !bets.contains(attempedBet4)) {
                    allRight = true;
                }
            }
            if (!allRight) {
                generateBets(bettor, entity);
            } else {
                entity.setBet1(betGenerator.nextInt(100));
                entity.setBet2(betGenerator.nextInt(100));
                entity.setBet3(betGenerator.nextInt(100));
                entity.setBet4(betGenerator.nextInt(100));
            }
        } catch (Exception e) {
            entity.setBet1(betGenerator.nextInt(100));
            entity.setBet2(betGenerator.nextInt(100));
            entity.setBet3(betGenerator.nextInt(100));
            entity.setBet4(betGenerator.nextInt(100));
        }
    }
    

    좋은 웹페이지 즐겨찾기