Spring Data JPA fait partie de la famille Spring Data. Spring Data facilite la création d’applications pilotées par Spring qui utilisent de nouvelles façons d’accéder aux données, telles que les bases de données non relationnelles, les frameworks de réduction de cartes, les services cloud, ainsi qu’une prise en charge avancée des bases de données relationnelles. Cet article abordera Spring Data JPA. Nous examinerons également un exemple d’application Spring Data JPA.
Spring Data JPA
Voici quelques-unes des fonctionnalités intéressantes fournies par Spring Data JPA :
- Créer et prendre en charge des référentiels créés avec Spring et JPA
- Prise en charge de QueryDSL et des requêtes JPA
- Audit des classes de domaine
- Prise en charge du chargement par lots, du tri et des requêtes dynamiques
- Prise en charge de la mise en correspondance XML pour les entités
- Réduire la taille du code pour les opérations génériques de CRUD en utilisant CrudRepository
Quand utiliser Spring Data JPA ?
I would say that if you need to quickly create a JPA-based repository layer that is mainly for CRUD operations, and you do not want to create abstract DAO, implementing interfaces, Spring Data JPA is a good choice.
Exemple de Spring Data JPA
Pour notre exemple Spring Data JPA, nous allons créer un service web RESTful qui se connectera à la base de données Postgresql. Nous implémenterons des opérations CRUD de base et travaillerons sur des données d’exemple que nous avons déjà créées.
Données d’exemple de l’exemple Spring JPA
Utilisez la requête ci-dessous pour créer une table dans la base de données Postgresql et ajouter quelques données de test.
create table people (
id serial not null primary key,
first_name varchar(20) not null,
last_name varchar(20) not null,
age integer not null
);
insert into people (id, first_name, last_name, age) values
(1, 'Vlad', 'Boyarskiy', 21),
(2,'Oksi', ' Bahatskaya', 30),
(3,'Vadim', ' Vadimich', 32);
Structure du projet Maven Spring Data JPA
L’image ci-dessous montre la structure finale du projet Spring JPA. Nous examinerons ensuite en détail chacun des composants.
Dépendances Maven Spring Data JPA
Nous devons ajouter les dépendances suivantes pour notre projet d’exemple Spring Data JPA.
postgresql
: Pilote Java Postgresql.spring-core
,spring-context
: Dépendances principales du framework Spring.spring-webmvc
,jackson-databind
: Pour une application REST avec Spring.spring-data-jpa
,hibernate-entitymanager
: Pour la prise en charge de Spring Data JPA et Hibernate.
Voici le contenu final du fichier de construction pom.xml.
<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.journaldev</groupId>
<artifactId>springData</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>Spring Data JPA Maven Webapp</name>
<url>https://maven.apache.org</url>
<properties>
<spring.framework>4.3.0.RELEASE</spring.framework>
<postgres.version>42.1.4</postgres.version>
<serializer.version>2.8.1</serializer.version>
<spring.data>1.3.4.RELEASE</spring.data>
<hibernate.manager>4.2.5.Final</hibernate.manager>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.framework}</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>${postgres.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.framework}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.framework}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>${spring.data}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${hibernate.manager}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${serializer.version}</version>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
</build>
</project>
Classes de configuration Spring
package com.journaldev.spring.config;
import java.util.Properties;
import javax.sql.DataSource;
import org.hibernate.ejb.HibernatePersistence;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories("com.journaldev.spring.repository")
@PropertySource("classpath:database.properties")
public class DataConfig {
private final String PROPERTY_DRIVER = "driver";
private final String PROPERTY_URL = "url";
private final String PROPERTY_USERNAME = "user";
private final String PROPERTY_PASSWORD = "password";
private final String PROPERTY_SHOW_SQL = "hibernate.show_sql";
private final String PROPERTY_DIALECT = "hibernate.dialect";
@Autowired
Environment environment;
@Bean
LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean lfb = new LocalContainerEntityManagerFactoryBean();
lfb.setDataSource(dataSource());
lfb.setPersistenceProviderClass(HibernatePersistence.class);
lfb.setPackagesToScan("com.journaldev.spring.model");
lfb.setJpaProperties(hibernateProps());
return lfb;
}
@Bean
DataSource dataSource() {
DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setUrl(environment.getProperty(PROPERTY_URL));
ds.setUsername(environment.getProperty(PROPERTY_USERNAME));
ds.setPassword(environment.getProperty(PROPERTY_PASSWORD));
ds.setDriverClassName(environment.getProperty(PROPERTY_DRIVER));
return ds;
}
Properties hibernateProps() {
Properties properties = new Properties();
properties.setProperty(PROPERTY_DIALECT, environment.getProperty(PROPERTY_DIALECT));
properties.setProperty(PROPERTY_SHOW_SQL, environment.getProperty(PROPERTY_SHOW_SQL));
return properties;
}
@Bean
JpaTransactionManager transactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
return transactionManager;
}
}
-
@Configuration
: cette annotation Spring indique qu’il s’agit d’une classe de configuration. -
@EnableTransactionManagement
: cette annotation permet aux utilisateurs d’utiliser la gestion des transactions dans l’application. -
@EnableJpaRepositories("com.journaldev.spring.repository")
: indique où se trouvent les classes de dépôt (repositories). -
@PropertySource("classpath:database.properties")
: indique que nous avons un fichier de propriétés dans notre classpath. Les valeurs de ce fichier seront injectées dans la variable d’environnement. Le contenu du fichier database.properties est indiqué ci-dessous.driver=org.postgresql.Driver url=jdbc:postgresql://127.0.0.1:5432/postgres user=postgres password=postgres hibernate.dialect=org.hibernate.dialect.PostgreSQL82Dialect hibernate.show_sql=true
-
Pour utiliser Spring Data, tout d’abord, nous devons configurer le bean
DataSource
. Ensuite, nous devons configurer le beanLocalContainerEntityManagerFactoryBean
. Nous avons besoin de ce bean pour contrôler les entités. Dans ces beans, vous devez spécifier le fournisseur de persistance, c’est-à-direHibernatePersistence
dans notre cas. -
La prochaine étape consiste à configurer le bean pour la gestion des transactions. Dans notre exemple, il s’agit de
JpaTransactionManager
. Notez qu’il est nécessaire de configurer le gestionnaire de transactions pour pouvoir utiliser l’annotation@Transactional
.
Les classes AppInitializer
et WebConfig
servent à configurer notre application en tant qu’application web sans utiliser le fichier web.xml.
Classe de modèle
package com.journaldev.spring.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "people")
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "age")
private Integer age;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
public Person() {
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
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;
}
@Override
public String toString() {
return "Person{" + "id=" + id + ", age=" + age + ", firstName='" + firstName + '\'' + ", lastName='" + lastName
+ '\'' + '}';
}
}
Ici, nous avons quelques nouvelles annotations. Parlons-en plus en détail.
- @Entity: Cette annotation permet au gestionnaire d’entité d’utiliser cette classe et de la mettre en contexte.
- @Table(name = « people »): Associe une classe à une table dans la base de données.
@Id
: Indique que ce champ est la clé primaire.@GeneratedValue(strategy = GenerationType.IDENTITY)
: Définit la stratégie de génération de la clé primaire.@Column(name = "age")
: indique une colonne dans la base de données avec laquelle ce champ sera associé.
Spring Data JPA Repository
La prochaine étape consiste à créer le référentiel JPA.
package com.journaldev.spring.repository;
import org.springframework.data.repository.CrudRepository;
import com.journaldev.spring.model.Person;
import java.util.List;
public interface PersonRepository<P> extends CrudRepository<Person, Long> {
List<Person> findByFirstName(String firstName);
}
En héritant de CrudRepository
, nous pouvons appeler de nombreuses méthodes sans avoir besoin de les implémenter nous-mêmes. Certaines de ces méthodes sont:
- save
- findOne
- exists
- findAll
- count
- delete
- deleteAll
Nous pouvons également définir nos propres méthodes. Ces noms de méthode doivent utiliser des mots-clés spéciaux tels que « find », « order » avec le nom des variables. Les développeurs de Spring Data JPA ont essayé de prendre en compte la majorité des options possibles dont vous pourriez avoir besoin. Dans notre exemple, la méthode findByFirstName(String firstName)
renvoie toutes les entrées de la table où le champ first_name
est égal à firstName
. Il s’agit de l’une des fonctionnalités les plus importantes de Spring Data JPA car elle réduit beaucoup de code répétitif. De plus, les chances d’erreurs sont moindres car ces méthodes Spring sont bien testées par de nombreux projets qui les utilisent déjà.
Classe de service Spring
Maintenant que notre code Spring Data JPA est prêt, la prochaine étape consiste à créer une classe de service et à définir les méthodes avec lesquelles nous devrons travailler avec la table de la base de données.
package com.journaldev.spring.services;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.journaldev.spring.model.Person;
import com.journaldev.spring.repository.PersonRepository;
@Service
public class PersonService {
@Autowired
PersonRepository<Person> personRepository;
@Transactional
public List<Person> getAllPersons() {
return (List<Person>) personRepository.findAll();
}
@Transactional
public List<Person> findByName(String name) {
return personRepository.findByFirstName(name);
}
@Transactional
public Person getById(Long id) {
return personRepository.findOne(id);
}
@Transactional
public void deletePerson(Long personId) {
personRepository.delete(personId);
}
@Transactional
public boolean addPerson(Person person) {
return personRepository.save(person) != null;
}
@Transactional
public boolean updatePerson(Person person) {
return personRepository.save(person) != null;
}
}
@Transactional
annotation indique que la méthode sera exécutée dans la transaction. Spring se chargera de la gestion de la transaction.
Classe de contrôleur Spring
La dernière étape consiste à créer la classe de contrôleur pour exposer nos API au monde extérieur.
package com.journaldev.spring.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.journaldev.spring.model.Person;
import com.journaldev.spring.services.PersonService;
@RestController
public class PersonController {
@Autowired
PersonService personService;
@RequestMapping(value = "/person/{id}", method = RequestMethod.GET)
public @ResponseBody Person getAllUsers(@PathVariable Long id) {
return personService.getById(id);
}
@RequestMapping(value = "/personByName/{name}", method = RequestMethod.GET)
public List<Person> getPersoneByName(@PathVariable String name) {
return personService.findByName(name);
}
@RequestMapping(value = "/person", method = RequestMethod.GET)
public List<Person> getAll() {
return personService.getAllPersons();
}
@RequestMapping(value = "/person/{id}", method = RequestMethod.DELETE)
public HttpStatus deletePersnone(@PathVariable Long id) {
personService.deletePerson(id);
return HttpStatus.NO_CONTENT;
}
@RequestMapping(value = "/person", method = RequestMethod.POST)
public HttpStatus insertPersone(@RequestBody Person person) {
return personService.addPerson(person) ? HttpStatus.CREATED : HttpStatus.BAD_REQUEST;
}
@RequestMapping(value = "/person", method = RequestMethod.PUT)
public HttpStatus updatePerson(@RequestBody Person person) {
return personService.updatePerson(person) ? HttpStatus.ACCEPTED : HttpStatus.BAD_REQUEST;
}
}
Tests Spring Data JPA
Il vous suffit de construire et déployer le projet dans votre conteneur de servlet préféré, tel que Tomcat. Les images ci-dessous montrent la réponse pour certaines des appels d’API.
Spring Data JPA Lire tout
Spring Data JPA Obtenir par nom
Spring Data JPA Créer
Spring Data JPA Mettre à jour
Spring Data JPA Supprimer
C’est tout pour le tutoriel exemple de Spring Data JPA. Vous pouvez télécharger le projet final depuis le lien ci-dessous.
Télécharger le projet exemple Spring Data JPA
Référence : Site officiel
Source:
https://www.digitalocean.com/community/tutorials/spring-data-jpa