JavaRush /Blog Java /Random-FR /Spring ne fait pas peur, ni comment remplir une base de d...
Павел
Niveau 11

Spring ne fait pas peur, ni comment remplir une base de données h2 (et un peu d'Hibernate)

Publié dans le groupe Random-FR
CONTENU DU CYCLE DES ARTICLES Nous poursuivons notre projet. Comment créer un projet Web. Nous connectons la base de données à notre projet Web . Cette fois, il y aura plus de lettres, on ne s’en sortira pas en cinq minutes. Dans le dernier article, je vous ai conseillé de lire plusieurs pages ou plusieurs articles sur Spring , ou au moins de chercher sur Google ce que sont les beans, le contexte, les entités, l'injection de dépendances dans Spring, les manières de configurer les beans. Sinon, je vous conseille de le faire maintenant ou après cet article. Avant de remplir notre base h2. Il est nécessaire de créer une classe utilitaire pour y exécuter des méthodes permettant de remplir la base de données. Dans le paquet
ru.java.rush
Création d'un package pour les utilitaires
utils
Et l'utilitaire lui-même :

package ru.java.rush.utils;

import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Service;

@Service //annotation помечает бин How сервис
public class InitiateUtils implements CommandLineRunner { //имплементируем интерфейс CommandLineRunner (командная строка запуска)
   
    @Override
//переопределяем метод который позволит 
//нам выполнять методы нашего applications при запуске
    public void run(String... args) throws Exception { 
        System.out.println("run"); //проверим что это работает
    }
}
Lançons l'application et "run" sera affiché dans la console . Nous avons besoin de cet utilitaire comme alternative à la classe Applications, car il ne devrait être responsable que du lancement de l'application. Créons des entités. Une entité est un bean dont le but est de stocker des données. Dans le paquet
ru.java.rush
Créer un package pour les entités
entities
Et l'essence elle-même, qu'elle porte fruit :

package ru.java.rush.entities;

import org.hibernate.annotations.GenericGenerator;

import javax.persistence.*;

@Entity//помечаем бин How сущность
@Table(name = "fruit_table")//в этой аннотации можно указать Name создаваемой таблицы 
public class FruitEntity {

    @Id//annotation из пакета avax.persistence.*, помечает поле How id
    @Column(name = "id_fruit")//в этой аннотации можно указать Name поля 
    @GenericGenerator(name = "generator", strategy = "increment")//незаметно добрались до hibernate,
// здесь указывается что id будет автоматически увеличиваться при новых записях  
    @GeneratedValue(generator = "generator")//annotation генерации id
    private Integer id;

    @Column(name = "fruit_name")
    private String fruitName;

    @Column(name = "provider_code")
    private Integer providerCode;

   //что бы в с классом можно было совершать манипуляции создается
  //пустой конструктор, геттеры, сеттеры и переопределяется метод toString()

  public FruitEntity(){ //пустой конструктор

 }

public Integer getId() {
    return id;
}

 //геттеры, сеттеры
public String getFruitName() {
    return fruitName;
}

public FruitEntity setFruitName(String fruitName) {
    this.fruitName = fruitName;
    return this;
}

public Integer getProviderCode() {
    return providerCode;
}

public FruitEntity setProviderCode(Integer providerCode) {
    this.providerCode = providerCode;
    return this;
}

//переопределяем toString()
@Override
public String toString() {
    return "FruitEntity{" +
            "id=" + id +
            ", fruitName='" + fruitName + '\'' +
            ", providerCode=" + providerCode +
            '}';
}
}
Le constructeur, les getters, les setters et toString() n'ont pas besoin d'être écrits à la main ; ils peuvent être générés rapidement . D'accord, notre entité interagit avec la base de données et stocke les données de la base de données. L'essentiel est à l'œuvre. Mais quelqu'un doit exploiter l'entité dans l'application. À cette fin, ils ont imaginé un « référentiel ». Dans le paquet
ru.java.rush
Création d'un package pour les référentiels
repositories
Et le référentiel lui-même

package ru.java.rush.repositories;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import ru.java.rush.entities.FruitEntity;

@Repository//помечаем что этот бин - репозиторий
public interface FruitRepository extends JpaRepository<FruitEntity,Integer> {
//репозиторий является интерфейсом, который наследуется от другого интерфейса JpaRepository<>
//для него необходимо указать с Howой сущность он должен работать, у нас это FruitEntity
//и тип данных у поля id данной сущности, у нас это Integer
}
La question est, pourquoi le corps de l'interface est-il vide, il n'y a pas une seule méthode qu'il déclare ? Pour répondre, maintenez Ctrl enfoncé et cliquez sur JpaRepository et voyez qu'il hérite lui-même de PagingAndSortingRepository<t, ""> et QueryByExampleExecutor<>, ils déclarent également certaines méthodes. Je ne copierai pas les méthodes ici ; cherchez par vous-même. Puisque le référentiel est une interface, il ne fait rien, il déclare seulement des méthodes, il faut quelqu'un d'autre pour implémenter ces méthodes. C'est pourquoi un « service » a été inventé. Dans le paquet
ru.java.rush
Création d'un package pour les services
services
Et le service lui-même

package ru.java.rush.services;

import org.springframework.stereotype.Service;

@Service//помечаем что этот бин - сервис
public class FruitService {
}
Nous arrivons désormais à un point important : « Comment et pourquoi injecter un bean » (injecter une dépendance). Si vous ne comprenez pas ce que je veux dire, alors je vous demande de lire sur ce sujet, maintenant ou plus tard, en faisant particulièrement attention aux méthodes « d'injection », combien il y en a, ce qui est meilleur, ce qui est pire, et pourquoi . Nous utilisons l'une des méthodes. Nous avons besoin que le « service » soit connecté d’une manière ou d’une autre au « référentiel ». Nous complétons notre service avec une annotation et une variable.

package ru.java.rush.services;

import org.springframework.stereotype.Service;
import ru.java.rush.repositories.FruitRepository;

@Service
public class FruitService {
    
    private final FruitRepository fruitRepository;  //final переменная репозитория 
    
public FruitService(FruitRepository fruitRepository) {//внедрor зависимость через конструктор
    this.fruitRepository = fruitRepository;
}

}
Vous pouvez maintenant implémenter la méthode à partir du « référentiel ». Nous complétons le « service »

package ru.java.rush.services;

import org.springframework.stereotype.Service;
import ru.java.rush.entities.FruitEntity;
import ru.java.rush.repositories.FruitRepository;

@Service
public class FruitService {

    private final FruitRepository fruitRepository;

public FruitService(FruitRepository fruitRepository) {//внедor зависимость
    this.fruitRepository = fruitRepository;
}

//создали публичный метод (название любое может быть)
//на вход принимает сущность и сохраняет ее в базу
    public void save(FruitEntity fruitEntity){ 
        fruitRepository.save(fruitEntity); //реализовали метод внедренного бина
    }

//возвращает лист всех сущностей из базы
    public List<FruitEntity> getAll(){
       return fruitRepository.findAll(); //реализовали метод внедренного бина
    }
}
Il ne reste plus qu'à implémenter cela dans notre utilitaire. Passons à la classe InitiateUtils

package ru.java.rush.utils;


import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Service;
import ru.java.rush.entities.FruitEntity;
import ru.java.rush.services.FruitService;

import java.util.List;

@Service
public class InitiateUtils implements CommandLineRunner {

    private final FruitService fruitService;

public InitiateUtils (FruitService fruitService) {//незабываем конструктор для внедрения
    this. fruitService = fruitService;
}

    @Override
    public void run(String... args) throws Exception {

//создаем несколько сущностей фруктов, через сеттеры заполняем поля
        FruitEntity fruitEntity1 = new FruitEntity();
        fruitEntity1.setFruitName("fruit1");
        fruitEntity1.setProviderCode(1);

        FruitEntity fruitEntity2 = new FruitEntity();
        fruitEntity2.setFruitName("fruit2");
        fruitEntity2.setProviderCode(2);

        FruitEntity fruitEntity3 = new FruitEntity();
        fruitEntity3.setFruitName("fruit3");
        fruitEntity3.setProviderCode(3);

//с помощью переменной сервиса вызываем методы сохранения в базу, по разу для одного an object
        fruitService.save(fruitEntity1);
        fruitService.save(fruitEntity2);
        fruitService.save(fruitEntity3);

//здесь вытаскиваем базу обратно
        List<FruitEntity> all = fruitService.getAll();

//и выводим что получилось
        for (FruitEntity entity : all) {
            System.out.println(entity);
        }
    }
}
Sortie de la console : FruitEntity(id=1, fruitName=fruit1, supplierCode=1) FruitEntity(id=2, fruitName=fruit2, supplierCode=2) FruitEntity(id=3, fruitName=fruit3, supplierCode=3) Ici, vous pouvez terminer. "Juste une seconde!" - s'exclamera le lecteur le plus attentif - "D'ailleurs, où est Hibernate ?" Et Hibernate agit ici comme un combattant sur le front invisible ; il a fait une chose très importante : il a créé pour nous des structures de bases de données. Lorsque nous avons écrit les champs dans « l'entité » et les avons marqués avec les annotations nécessaires, Hibernate a fait son travail. En fait, lors du développement à la volée, il est peu probable que vous ayez à gérer la structure de la base de données : tout sera déjà créé et déployé pour vous. Mais dans de si petits projets, Hibernate, avec sa capacité à créer des structures de bases de données, ne peut tout simplement pas être remplacé ; bien sûr, ce n'est pas son seul avantage, par exemple, il est bon pour créer des entités liées (nous ne les utiliserons pas dans ce projet). Disons bonjour à cet humble travailleur : allez dans IDEA dans la structure du projet (à gauche il y a une arborescence avec des dossiers et des fichiers), là nous trouverons des bibliothèques externes, ouvrez-la et voyez-la parmi d'autres bibliothèques

Maven: org.hibernate.common:hibernate-commons-annotations:5.1.0.Final
Maven: org.hibernate.validator:hibernate-validator:6.0.17.Final
Maven: org.hibernate:hibernate-core:5.4.6.Final
Hibernate a notamment été téléchargé pour nous par Maven et

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
En fait, M. Hiber a mené une autre opération secrète, mais nous en reparlerons dans le prochain article. C'est tout sûr maintenant. À titre d'exercice de formation, je vous suggère d'implémenter vous-même la méthode saveAll() pour FruitEntity , qui enregistrera toutes les entités dans la base de données en même temps. Voyons ensuite comment raccourcir le code du projet à l'aide de la bibliothèque Lombok.
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION