Je n'avais jamais touché à un OR Mapper autre que Doma, alors j'y ai soudainement pensé et l'ai touché avec un demi-intérêt.
Comment installer dans l'application Spring Boot - Je voudrais écrire sur la comparaison avec Doma que j'ai ressentie en créant une API simple.
IDE VSCode
Java 11.0.6
Spring Boot 2.3.1
PostgreSQL 11.6
Je voudrais créer une API simple et la toucher de différentes manières. L'API à créer est la suivante.
point final | Http Method | Aperçu | Remarques |
---|---|---|---|
/api/employee/{employeeId} |
GET | Obtenez des informations sur les employés qui correspondent à l'ID d'employé. | |
/api/employee |
GET | Obtenez des informations sur les employés. | Nous allons également affiner par conditions de recherche. |
/api/employee |
POST | Enregistrez les informations sur les employés. | |
/api/employee/{employeeId} |
PUT | Mettez à jour les informations sur les employés. | |
/api/employee/{employeeId} |
DELETE | Supprimer les informations sur les employés. |
Créez un modèle pour votre application à l'aide du plug-in VS Code appelé Spring Initializer Java Support.
Ce plug-in lui-même est inclus dans le Spring Boot Extension Pack, donc le [Spring Boot Extension Pack]( Il suffit d'avoir https://marketplace.visualstudio.com/items?itemName=Pivotal.vscode-boot-dev-pack) installé.
Créez un modèle de manière interactive. Dans la palette de commandes, sélectionnez "Spring Initializr: Générer un projet Gradle".
Sélectionnez Java.
Entrez le nom du package. Cette fois, laissez-le par défaut comme «com.example».
Saisissez le nom du projet. Veuillez nous donner votre nom préféré. (J'ai utilisé des employés-api.)
Sélectionnez la version de Spring Boot. (Sélectionnez 2.3.1)
Sélectionnez une bibliothèque dépendante. J'ai choisi la bibliothèque suivante car je voulais juste créer une API simple.
Spring Boot DevTools / Lombok / Spring Web / Spring Data JPA / PostgreSQL Driver
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 et ʻupdate_date
sont définis comme des éléments communs dans la table.
CommonEntity.java
/**
*Une classe qui définit les éléments communs dans une table.</br>
*Toutes les classes Entity sont créées en héritant de cette classe.
*/
@MappedSuperclass
@Getter
@Setter
public class CommonEntity {
/**Date et heure d'enregistrement des données*/
@Column(name = "insert_date")
@Temporal(TemporalType.DATE)
private Date insertdate;
/**Date et heure de mise à jour des données*/
@Column(name = "update_date")
@Temporal(TemporalType.DATE)
private Date updateDate;
/**
*Méthode couramment exécutée avant l'enregistrement des données
*/
@PrePersist
public void preInsert() {
Date date = new Date();
setInsertdate(date);
setUpdateDate(date);
}
/**
*Méthodes couramment exécutées avant la mise à jour des données
*/
@PreUpdate
public void preUpdate() {
setUpdateDate(new Date());
}
}
Hérite de CommonEntity
qui définit les éléments de table communs et crée une classe Entity à usage professionnel.
EmployeeEntity.java
@Entity
@Table(name = "employee")
@Getter
@Setter
public class EmployeeEntity extends CommonEntity {
/**ID d'employé*/
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer employeeId;
/**Nom de l'employé*/
@Column(name = "name")
private String employeeName;
/**âge*/
@Column(name = "age")
private Integer age;
/**ID de position*/
@Column(name = "position_id")
private String positionId;
/**ID de service*/
@Column(name = "department_id")
private String departmentId;
}
ʻDéfinissez une interface qui hérite de org.springframework.data.jpa.repository.JpaRepository`.
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
Il existe des méthodes qui peuvent gérer les opérations CRUD de base. Dans l'interface qui hérite de cette interface (dans cet exemple, ʻEmployeeRepository`), vous pouvez définir votre propre méthode lorsque la méthode préparée à l'avance dans les spécifications métier, etc. n'est pas suffisante. (Rejoignez-nous pour obtenir des enregistrements, etc.)
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);
}
Définissez une classe Service qui utilise le ʻEmployee Repository` défini précédemment et une classe Controller qui l'appelle.
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) {
//Pour l'exemple, faites une simple copie.
//Si vous voulez le faire proprement, BeanUtils#Utilisez copyProperties, etc.
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) {
//Pour l'exemple, faites une simple copie.
//Si vous voulez le faire proprement, BeanUtils#Utilisez copyProperties, etc.
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) {
//Pour l'exemple, faites une simple copie.
//Si vous voulez le faire proprement, BeanUtils#Utilisez copyProperties, etc.
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;
}
}
Je l'ai écrit en comparaison avec d'autres OR Mappers, mais c'est une comparaison avec Doma.
――Ce que je ressentais était bon
JpaRepository
, Doma Gen semble être tout à fait le cas, mais ,La base de données de vérification est construite sur la base de Docker. C'est pénible de créer une base de données car cela fonctionne avec le copier-coller! Veuillez l'utiliser.
$ 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 (
--Code départemental
id varchar(3) primary key,
--Nom du département
name varchar(50),
--Date d'entrée des données
insert_date date,
--Date de mise à jour des données
update_date date
);
create table "position" (
--ID de position
id varchar(2) primary key,
--Titre
name varchar(20),
--Date d'entrée des données
insert_date date,
--Date de mise à jour des données
update_date date
);
--génération de table
create table "employee" (
--numéro d'employé
id serial primary key,
--Nom de l'employé
name varchar(50),
--âge
age integer,
--Position
position_id varchar(2) references position(id),
--Identifiant du service d'affiliation
department_id varchar(3) references department(id),
--Date d'entrée des données
insert_date date,
--Date de mise à jour des données
update_date date
);
02_insert_data.sql
insert into department (id, name, insert_date, update_date)
values ('001', 'Département des Ressources Humaines', '2020-06-17', '2020-06-17');
insert into department (id, name, insert_date, update_date)
values ('002', 'Département des affaires générales', '2020-06-17', '2020-06-17');
insert into department (id, name, insert_date, update_date)
values ('003', 'Département de développement', '2020-06-17', '2020-06-17');
insert into department (id, name, insert_date, update_date)
values ('004', 'Département des relations publiques', '2020-06-17', '2020-06-17');
insert into position (id, name, insert_date, update_date)
values ('01', 'Réalisateur', '2020-06-17', '2020-06-17');
insert into position (id, name, insert_date, update_date)
values ('02', 'Directeur', '2020-06-17', '2020-06-17');
insert into position (id, name, insert_date, update_date)
values ('03', 'Général', '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'
);
J'aimerais imaginer un cas d'utilisation réel et créer une API plus pratique.
Se connecter à la base de données avec SpringBoot + Spring JPA
Connectez-vous à la base de données avec spring boot + spring jpa et effectuez l'opération CRUD
Recommended Posts