При создании обычного CRUD контроллера разработчик обычно делает несколько вещей.

  1. Создает Entity

  2. Пишет миграцию в БД

  3. Создает DTO для Entity

  4. Создает слой Repository

  5. Создает слой Service

  6. Создает слой Controller

Многие из этих вещей можно сделать автоматически с помощью ChatGPT. И так сразу к делу, и посмотрим на что способен ChatGPT. В качестве Entity будем использовать простой класс.

@Entity
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE)
public class Client {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

  /**
   * Имя клиента
   */
  String firstName;

  /**
   * Фамилия клиента
   */
  String lastName;

  /**
   * Номер телефона клиента
   */
  String phoneNumber;

  /**
   * Айди в кейклоке для зарегистрированных клиентов, пустое поле для незарегистрированных
   */
  UUID keycloakId;

  /**
   * Филиал, к которому относится клиент
   */
  @ManyToOne(fetch = FetchType.LAZY)
  Place place;

}

Мы создали простой Entity, дальше мы будем пытаться через Chat GPT создать все остальные слои логики. Для этой Entity. В формате "Цитат" я буду писать какие запросы я отправляю в ChatGPT, и в формате кода это ответы от этой потрясающей технологии.

И так начнем...

Сделай из этого Java класса DTO

public class ClientDTO {
   private String firstName;
   private String lastName;
   private String phoneNumber;
   private UUID keycloakId;
   private LocalDate createdDate;

   public ClientDTO(String firstName, String lastName, String phoneNumber, UUID keycloakId, LocalDate createdDate) {
      this.firstName = firstName;
      this.lastName = lastName;
      this.phoneNumber = phoneNumber;
      this.keycloakId = keycloakId;
      this.createdDate = createdDate;
   }

   public String getFirstName() {
      return firstName;
   }

   public void setFirstName(String firstName) {
      this.firstName = firstName;
   }

   public String getLastName() {
      return lastName;
   }

   public void setLastName(String lastName) {
      this.lastName = lastName;
   }

   public String getPhoneNumber() {
      return phoneNumber;
   }

   public void setPhoneNumber(String phoneNumber) {
      this.phoneNumber = phoneNumber;
   }

   public UUID getKeycloakId() {
      return keycloakId;
   }

   public void setKeycloakId(UUID keycloakId) {
      this.keycloakId = keycloakId;
   }

   public LocalDate getCreatedDate() {
      return createdDate;
   }

   public void setCreatedDate(LocalDate createdDate) {
      this.createdDate = createdDate;
   }
}

Очень не плохо, но не хватает Lombok-a

Добавь в этот класс Lombok

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class ClientDTO {
   private String firstName;
   private String lastName;
   private String phoneNumber;
   private UUID keycloakId;
   private LocalDate createdDate;
}

Уверен если попросить GPT сразу сгенерировать класс с Lombok, то он это сделает. Но я ведь не уточнял, что надо сгенерировать именно с Lombok.

Даже нейронная сеть понимает что без четкого ТЗ результат ХЗ

Сделай из Entity CRUD репозиторий

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface ClientRepository extends JpaRepository<Client, Long> {

}

Сделай из Entity CRUD Service, со следующими методами:
1. Получение пагинированного списка
2. Получение по ID
3. Удаление по ID
4. Создание новой записи

@Service
public class ClientService {

  private final ClientRepository clientRepository;

  @Autowired
  public ClientService(ClientRepository clientRepository) {
    this.clientRepository = clientRepository;
  }

  public Page<Client> getAllClients(Pageable pageable) {
    return clientRepository.findAll(pageable);
  }

  public Optional<Client> getClientById(UUID id) {
    return clientRepository.findById(id);
  }

  public void deleteClientById(UUID id) {
    clientRepository.deleteById(id);
  }

  public Client createClient(Client client) {
    return clientRepository.save(client);
  }
}

Сделай из Entity миграцию в Postgresql

CREATE TABLE Client (
  id SERIAL PRIMARY KEY,
  first_name VARCHAR(255) NOT NULL,
  last_name VARCHAR(255) NOT NULL,
  phone_number VARCHAR(255) NOT NULL,
  keycloak_id UUID NOT NULL,
  place_id INTEGER NOT NULL,
  FOREIGN KEY (place_id) REFERENCES Place(id)
);

Сгенерируй из этой DTO:

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class ClientDTO {
private String firstName;
private String lastName;
private String phoneNumber;
private UUID keycloakId;
private LocalDate createdDate;
}

JSON формат с Mock данными

{
   "firstName": "John",
   "lastName": "Doe",
   "phoneNumber": "1234567890",
   "keycloakId": "1b7f00c9-2aaf-4c28-a7b8-aeb0c7dfc8f0",
   "createdDate": "2022-01-01"
}
Хочу отметить что он дал дельные замечания касательно UUID
Хочу отметить что он дал дельные замечания касательно UUID

Напиши Unit тесты на этот класс

Ответ от Chat GPT

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.verify;

import java.util.Arrays;
import java.util.Optional;
import java.util.UUID;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;

@RunWith(MockitoJUnitRunner.class)
public class ClientServiceTest {

  @Mock
  private ClientRepository clientRepository;

  private ClientService clientService;

  @Before
  public void setUp() {
    clientService = new ClientService(clientRepository);
  }

  @Test
  public void getAllClients_shouldReturnAllClients() {
    // given
    Client client1 = new Client();
    client1.setId(UUID.randomUUID());
    client1.setFirstName("John");
    client1.setLastName("Doe");

    Client client2 = new Client();
    client2.setId(UUID.randomUUID());
    client2.setFirstName("Jane");
    client2.setLastName("Doe");

    Page<Client> clientsPage = new PageImpl<>(Arrays.asList(client1, client2));
    Pageable pageable = PageRequest.of(0, 10);

    doReturn(clientsPage).when(clientRepository).findAll(any(Pageable.class));

    // when
    Page<Client> result = clientService.getAllClients(pageable);

    // then
    assertThat(result.getTotalElements()).isEqualTo(2);
    assertThat(result.getContent().get(0).getFirstName()).isEqualTo("John");
    assertThat(result.getContent().get(1).getFirstName()).isEqualTo("Jane");
  }

  @Test
  public void getClientById_shouldReturnClient() {
    // given
    UUID id = UUID.randomUUID();

    Client client = new Client();
    client.setId(id);
    client.setFirstName("John");
    client.setLastName("Doe");

    doReturn(Optional.of(client)).when(clientRepository).findById(id);

    // when
    Optional<Client> result = clientService.getClientById(id);

    // then
    assertThat(result.isPresent()).isTrue();
    assertThat(result.get().getFirstName()).isEqualTo("John");
    assertThat(result.get().getLastName()).isEqualTo("Doe");

К сожалению тесты он часто не заканчивает.... И тесты которые он пишет довольно сомнительного качества.

Вывод. Chat GPT инструмент который уже сейчас, может помочь программисту в повседневной работе, ускоряя его работу. Это полезный инструмент который позволит немного экономить время на создании новых классов.

Это не тот инструмент на который можно положиться на 100%. Есть страхи что Junior разработчики будут бездумно использовать его. Но если вы опытный программист, то вам достаточно сделать пару запросов в ChatGPT получить от него ответы, провести Code Review, поправить косяки и использовать его код в работе.

Комментарии (2)


  1. yoigo
    00.00.0000 00:00

    Довольно интересно. Спасибо.


  1. upagge
    00.00.0000 00:00

    Не очень понял про “дельные замечания про uuid”?

    И ответы будут лучше, если формировать запросы на английском.