ChatGPT и Java Back-End Spring Boot
При создании обычного CRUD контроллера разработчик обычно делает несколько вещей.
Создает Entity
Пишет миграцию в БД
Создает DTO для Entity
Создает слой Repository
Создает слой Service
Создает слой 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"
}
Напиши 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, поправить косяки и использовать его код в работе.