Ich hatte noch nie einen anderen OP-Mapper als Doma berührt, also dachte ich plötzlich darüber nach und berührte ihn mit halbem Interesse.
Installation in einer Spring Boot-Anwendung - Ich möchte über den Vergleich mit Doma schreiben, den ich durch das Erstellen einer einfachen API empfand.
IDE VSCode
Java 11.0.6
Spring Boot 2.3.1
PostgreSQL 11.6
Ich möchte eine einfache API erstellen und sie auf verschiedene Arten berühren. Die zu erstellende API lautet wie folgt.
Endpunkt | Http Method | Überblick | Bemerkungen |
---|---|---|---|
/api/employee/{employeeId} |
GET | Abrufen von Mitarbeiterinformationen, die mit der Mitarbeiter-ID übereinstimmen. | |
/api/employee |
GET | Mitarbeiterinformationen abrufen. | Wir werden auch nach Suchbedingungen eingrenzen. |
/api/employee |
POST | Registrieren Sie Mitarbeiterinformationen. | |
/api/employee/{employeeId} |
PUT | Aktualisieren Sie die Mitarbeiterinformationen. | |
/api/employee/{employeeId} |
DELETE | Mitarbeiterinformationen löschen. |
Erstellen Sie eine Vorlage für Ihre Anwendung mit dem VSCode-Plug-In Spring Initializer Java Support.
Dieses Plugin selbst ist im Spring Boot Extension Pack enthalten, also im [Spring Boot Extension Pack]( Es reicht aus, https://marketplace.visualstudio.com/items?itemName=Pivotal.vscode-boot-dev-pack) installiert zu haben.
Erstellen Sie interaktiv eine Vorlage. Wählen Sie in der Befehlspalette "Spring Initializr: Generate a Gradle Project" aus.
Wählen Sie Java.
Geben Sie den Paketnamen ein. Lassen Sie es diesmal standardmäßig als "com.example".
Geben Sie den Projektnamen ein. Bitte geben Sie uns Ihren Lieblingsnamen. (Ich habe Employee-API verwendet.)
Wählen Sie die Version von Spring Boot. (Wählen Sie 2.3.1)
Wählen Sie eine abhängige Bibliothek aus. Ich habe die folgende Bibliothek ausgewählt, weil ich nur eine einfache API erstellen wollte.
Spring Boot DevTools / Lombok / Spring Web / Spring Data JPA / PostgreSQL Driver
application.properties
spring.jpa.database=postgresql
spring.datasource.platform=postgres
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://localhost:5432/sample
spring.datasource.username=postgres
spring.datasource.password=postgres
Insert_date
und update_date
sind als allgemeine Elemente in der Tabelle definiert.
CommonEntity.java
/**
*Eine Klasse, die allgemeine Elemente in einer Tabelle definiert.</br>
*Alle Entitätsklassen werden durch Erben dieser Klasse erstellt.
*/
@MappedSuperclass
@Getter
@Setter
public class CommonEntity {
/**Datum und Uhrzeit der Datenregistrierung*/
@Column(name = "insert_date")
@Temporal(TemporalType.DATE)
private Date insertdate;
/**Datum und Uhrzeit der Datenaktualisierung*/
@Column(name = "update_date")
@Temporal(TemporalType.DATE)
private Date updateDate;
/**
*Häufig ausgeführte Methode vor der Datenregistrierung
*/
@PrePersist
public void preInsert() {
Date date = new Date();
setInsertdate(date);
setUpdateDate(date);
}
/**
*Häufig ausgeführte Methoden vor dem Aktualisieren von Daten
*/
@PreUpdate
public void preUpdate() {
setUpdateDate(new Date());
}
}
Erben Sie "CommonEntity", das allgemeine Tabellenelemente definiert und eine Entitätsklasse für den geschäftlichen Gebrauch erstellt.
EmployeeEntity.java
@Entity
@Table(name = "employee")
@Getter
@Setter
public class EmployeeEntity extends CommonEntity {
/**Mitarbeiter-ID*/
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer employeeId;
/**Mitarbeitername*/
@Column(name = "name")
private String employeeName;
/**Alter*/
@Column(name = "age")
private Integer age;
/**Positions-ID*/
@Column(name = "position_id")
private String positionId;
/**Abteilungs-ID*/
@Column(name = "department_id")
private String departmentId;
}
Definiert eine Schnittstelle, die "org.springframework.data.jpa.repository.JpaRepository" erbt.
EmployeeRepository.java
package com.example.employeeapi.employee;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface EmployeeRepository extends JpaRepository<EmployeeEntity, Integer> {
}
JpaRepository
Es gibt Methoden, die grundlegende CRUD-Operationen verarbeiten können. In der Schnittstelle, die diese Schnittstelle erbt (in diesem Beispiel "EmployeeRepository"), können Sie Ihre eigene Methode definieren, wenn die im Voraus in den Geschäftsspezifikationen usw. vorbereitete Methode nicht ausreicht. (Beitreten, um Aufzeichnungen usw. zu erhalten)
JpaRepository.java
/*
* Copyright 2008-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.jpa.repository;
import java.util.List;
import javax.persistence.EntityManager;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Sort;
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.QueryByExampleExecutor;
/**
* JPA specific extension of {@link org.springframework.data.repository.Repository}.
*
* @author Oliver Gierke
* @author Christoph Strobl
* @author Mark Paluch
*/
@NoRepositoryBean
public interface JpaRepository<T, ID> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> {
/*
* (non-Javadoc)
* @see org.springframework.data.repository.CrudRepository#findAll()
*/
@Override
List<T> findAll();
/*
* (non-Javadoc)
* @see org.springframework.data.repository.PagingAndSortingRepository#findAll(org.springframework.data.domain.Sort)
*/
@Override
List<T> findAll(Sort sort);
/*
* (non-Javadoc)
* @see org.springframework.data.repository.CrudRepository#findAll(java.lang.Iterable)
*/
@Override
List<T> findAllById(Iterable<ID> ids);
/*
* (non-Javadoc)
* @see org.springframework.data.repository.CrudRepository#save(java.lang.Iterable)
*/
@Override
<S extends T> List<S> saveAll(Iterable<S> entities);
/**
* Flushes all pending changes to the database.
*/
void flush();
/**
* Saves an entity and flushes changes instantly.
*
* @param entity
* @return the saved entity
*/
<S extends T> S saveAndFlush(S entity);
/**
* Deletes the given entities in a batch which means it will create a single {@link Query}. Assume that we will clear
* the {@link javax.persistence.EntityManager} after the call.
*
* @param entities
*/
void deleteInBatch(Iterable<T> entities);
/**
* Deletes all entities in a batch call.
*/
void deleteAllInBatch();
/**
* Returns a reference to the entity with the given identifier. Depending on how the JPA persistence provider is
* implemented this is very likely to always return an instance and throw an
* {@link javax.persistence.EntityNotFoundException} on first access. Some of them will reject invalid identifiers
* immediately.
*
* @param id must not be {@literal null}.
* @return a reference to the entity with the given identifier.
* @see EntityManager#getReference(Class, Object) for details on when an exception is thrown.
*/
T getOne(ID id);
/*
* (non-Javadoc)
* @see org.springframework.data.repository.query.QueryByExampleExecutor#findAll(org.springframework.data.domain.Example)
*/
@Override
<S extends T> List<S> findAll(Example<S> example);
/*
* (non-Javadoc)
* @see org.springframework.data.repository.query.QueryByExampleExecutor#findAll(org.springframework.data.domain.Example, org.springframework.data.domain.Sort)
*/
@Override
<S extends T> List<S> findAll(Example<S> example, Sort sort);
}
Definieren Sie eine Service-Klasse, die das zuvor definierte "EmployeeRepository" verwendet, und eine Controller-Klasse, die es aufruft.
EmployeeService.java
package com.example.employeeapi.employee;
import java.util.ArrayList;
import java.util.List;
import javax.transaction.Transactional;
import com.example.employeeapi.employee.dto.Employee;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
@Transactional
public class EmployeeService {
@Autowired
private EmployeeRepository employeeRepository;
public Employee getEmployeeById(String employeeId) {
EmployeeEntity entity = employeeRepository.findById(Integer.parseInt(employeeId)).get();
Employee employee = new Employee();
copyEntityToBean(entity, employee);
return employee;
}
public List<Employee> getEmployeeList() {
List<Employee> employees = new ArrayList<>();
List<EmployeeEntity> employeeEntityList = employeeRepository.findAll();
employeeEntityList.forEach(entity -> {
Employee employee = new Employee();
copyEntityToBean(entity, employee);
employees.add(employee);
});
return employees;
}
public Employee createEmployee(Employee employee) {
EmployeeEntity entity = new EmployeeEntity();
copyBeanToEntityForInsert(employee, entity);
EmployeeEntity createdEntity = employeeRepository.save(entity);
Employee newEmployee = new Employee();
copyEntityToBean(createdEntity, newEmployee);
return newEmployee;
}
public Employee updateEmployee(Employee employee) {
EmployeeEntity entity = new EmployeeEntity();
copyBeanToEntityForUpdate(employee, entity);
EmployeeEntity updatedEntity = employeeRepository.save(entity);
Employee updatedEmployee = new Employee();
copyEntityToBean(updatedEntity, updatedEmployee);
return updatedEmployee;
}
public boolean deleteEmployeeById(String employeeId) {
employeeRepository.deleteById(Integer.parseInt(employeeId));
return true;
}
private void copyEntityToBean(EmployeeEntity entity, Employee employee) {
//Erstellen Sie für das Beispiel eine einfache Kopie.
//Wenn Sie es sauber machen wollen, BeanUtils#Verwenden Sie copyProperties usw.
employee.setId(String.valueOf(entity.getEmployeeId()));
employee.setName(entity.getEmployeeName());
employee.setAge(String.valueOf(entity.getAge()));
employee.setPositionId(entity.getPositionId());
employee.setDepartmentId(entity.getDepartmentId());
employee.setInsertDate(String.valueOf(entity.getInsertdate()));
employee.setUpdateDate(String.valueOf(entity.getUpdateDate()));
}
private void copyBeanToEntityForInsert(Employee employee, EmployeeEntity entity) {
//Erstellen Sie für das Beispiel eine einfache Kopie.
//Wenn Sie es sauber machen wollen, BeanUtils#Verwenden Sie copyProperties usw.
if (!"".equals(employee.getName())) {
entity.setEmployeeName(employee.getName());
}
if (!"".equals(employee.getAge())) {
entity.setAge(Integer.parseInt(employee.getAge()));
}
if (!"".equals(employee.getPositionId())) {
entity.setPositionId(employee.getPositionId());
}
if (!"".equals(employee.getDepartmentId())) {
entity.setDepartmentId(employee.getDepartmentId());
}
}
private void copyBeanToEntityForUpdate(Employee employee, EmployeeEntity entity) {
//Erstellen Sie für das Beispiel eine einfache Kopie.
//Wenn Sie es sauber machen wollen, BeanUtils#Verwenden Sie copyProperties usw.
entity.setEmployeeId(Integer.parseInt(employee.getId()));
copyBeanToEntityForInsert(employee, entity);
}
}
EmployeeController.java
package com.example.employeeapi.employee;
import java.util.List;
import com.example.employeeapi.common.dto.HttpResponseDto;
import com.example.employeeapi.employee.dto.Employee;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class EmployeeController {
@Autowired
private EmployeeService employeeService;
@GetMapping(path = "/api/employee/{employeeId}")
public HttpResponseDto getEmployeeById(@PathVariable("employeeId") String employeeId) {
HttpResponseDto httpResponseDto = new HttpResponseDto();
Employee employee = employeeService.getEmployeeById(employeeId);
httpResponseDto.setHttpStatus(HttpStatus.OK);
httpResponseDto.setResponseData(employee);
return httpResponseDto;
}
@GetMapping(path = "/api/employee")
public HttpResponseDto getEmployeeList() {
HttpResponseDto httpResponseDto = new HttpResponseDto();
List<Employee> employees = employeeService.getEmployeeList();
httpResponseDto.setHttpStatus(HttpStatus.OK);
httpResponseDto.setResponseData(employees);
return httpResponseDto;
}
@PostMapping(path = "/api/employee")
public HttpResponseDto createEmployee(@RequestBody Employee employee) {
HttpResponseDto httpResponseDto = new HttpResponseDto();
Employee newEmployee = employeeService.createEmployee(employee);
httpResponseDto.setHttpStatus(HttpStatus.CREATED);
httpResponseDto.setResponseData(newEmployee);
return httpResponseDto;
}
@PutMapping(path = "/api/employee/{employeeId}")
public HttpResponseDto updateEmployee(@PathVariable("employeeId") String emplyeeId, @RequestBody Employee employee) {
HttpResponseDto httpResponseDto = new HttpResponseDto();
employee.setId(emplyeeId);
Employee updatedEmployee = employeeService.updateEmployee(employee);
httpResponseDto.setHttpStatus(HttpStatus.CREATED);
httpResponseDto.setResponseData(updatedEmployee);
return httpResponseDto;
}
@DeleteMapping(path = "/api/employee/{employeeId}")
public HttpResponseDto deleteEmployee(@PathVariable("employeeId") String employeeId) {
HttpResponseDto httpResponseDto = new HttpResponseDto();
if (employeeService.deleteEmployeeById(employeeId)) {
httpResponseDto.setHttpStatus(HttpStatus.OK);
httpResponseDto.setMessage("delete success.");
} else {
// do something
}
return httpResponseDto;
}
}
Ich habe es als Vergleich mit anderen OP-Mappern geschrieben, aber es ist ein Vergleich mit Doma.
»Was ich fühlte, war gut
JpaRepository
bereitgestellte API geht, scheint Doma Gen ganz so zu sein, aber ,Die Verifizierungsdatenbank basiert auf Docker. Es ist mühsam, eine Datenbank zu erstellen, da sie mit Kopieren und Einfügen funktioniert! Bitte benutzen Sie es.
$ tree
.
├── docker-compose.yml
└── init-script
├── 01_create_table.sql
└── 02_insert_data.sql
docker-compose.yml
version: '3'
volumes:
db_data:
services:
database:
image: postgres:11.6
container_name: postgres
ports:
- 5432:5432
volumes:
- db_data:/var/lib/postgresql/data
- ./init-script:/docker-entrypoint-initdb.d
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: sample
01_create_table.sql
create table department (
--Abteilungscode
id varchar(3) primary key,
--Abteilungsname
name varchar(50),
--Dateneingabedatum
insert_date date,
--Datum der Datenaktualisierung
update_date date
);
create table "position" (
--Positions-ID
id varchar(2) primary key,
--Titel
name varchar(20),
--Dateneingabedatum
insert_date date,
--Datum der Datenaktualisierung
update_date date
);
--Tabellengenerierung
create table "employee" (
--Mitarbeiternummer
id serial primary key,
--Mitarbeitername
name varchar(50),
--Alter
age integer,
--Position
position_id varchar(2) references position(id),
--ID der Zugehörigkeitsabteilung
department_id varchar(3) references department(id),
--Dateneingabedatum
insert_date date,
--Datum der Datenaktualisierung
update_date date
);
02_insert_data.sql
insert into department (id, name, insert_date, update_date)
values ('001', 'Personalabteilung', '2020-06-17', '2020-06-17');
insert into department (id, name, insert_date, update_date)
values ('002', 'Abteilung Allgemeine Angelegenheiten', '2020-06-17', '2020-06-17');
insert into department (id, name, insert_date, update_date)
values ('003', 'Entwicklungsabteilung', '2020-06-17', '2020-06-17');
insert into department (id, name, insert_date, update_date)
values ('004', 'Abteilung für Öffentlichkeitsarbeit', '2020-06-17', '2020-06-17');
insert into position (id, name, insert_date, update_date)
values ('01', 'Direktor', '2020-06-17', '2020-06-17');
insert into position (id, name, insert_date, update_date)
values ('02', 'Manager', '2020-06-17', '2020-06-17');
insert into position (id, name, insert_date, update_date)
values ('03', 'Allgemeines', '2020-06-17', '2020-06-17');
insert into employee (
name,
age,
position_id,
department_id,
insert_date,
update_date
)
values (
'Shacho-san',
50,
'01',
'001',
'2020-06-17',
'2020-06-17'
);
insert into employee (
name,
age,
position_id,
department_id,
insert_date,
update_date
)
values (
'Butcho-san',
46,
'02',
'001',
'2020-06-17',
'2020-06-17'
);
insert into employee (
name,
age,
position_id,
department_id,
insert_date,
update_date
)
values (
'Kaccho',
30,
'03',
'001',
'2020-06-17',
'2020-06-17'
);
insert into employee (
name,
age,
position_id,
department_id,
insert_date,
update_date
)
values (
'Pampy',
30,
'03',
'002',
'2020-06-17',
'2020-06-17'
);
Ich möchte mir einen realen Anwendungsfall vorstellen und eine praktischere API erstellen.
Mit SpringBoot + Spring JPA eine Verbindung zur Datenbank herstellen
Mit Spring Boot + Spring JPA eine Verbindung zur Datenbank herstellen und CRUD-Operation ausführen
Recommended Posts