JavaRush /בלוג Java /Random-HE /אביב לא מפחיד, או איך לאכלס מסד נתונים h2 (וקצת שינה)
Павел
רָמָה

אביב לא מפחיד, או איך לאכלס מסד נתונים h2 (וקצת שינה)

פורסם בקבוצה
תוכן מחזור המאמרים אנו ממשיכים בפרויקט שלנו. כיצד ליצור פרויקט אינטרנט. אנו מחברים את מסד הנתונים לפרויקט האינטרנט שלנו . הפעם יהיו יותר מכתבים, לא נסתדר תוך חמש דקות. במאמר האחרון, המלצתי לך לקרוא מספר עמודים או מספר מאמרים על ספרינג , או לפחות לחפש בגוגל על ​​מה זה שעועית, הקשר, ישויות, הזרקת תלות באביב, דרכים להגדיר שעועית. אם לא, אז אני ממליץ לך לעשות את זה עכשיו או אחרי מאמר זה. לפני מילוי בסיס h2 שלנו. יש צורך ליצור מחלקת עזר כדי להפעיל שיטות למילוי מסד הנתונים בו. בחבילה
ru.java.rush
יצירת חבילה עבור כלי עזר
utils
והשירות עצמו:
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"); //проверим что это работает
    }
}
הבה נריץ את האפליקציה ו"הפעלה " יוצג במסוף . אנו זקוקים לכלי השירות הזה כחלופה למחלקה Applications, מכיוון שהיא צריכה להיות אחראית רק להפעלת האפליקציה. בואו ניצור ישויות. ישות היא שעועית שמטרתה לאחסן נתונים מסוימים. בחבילה
ru.java.rush
צור חבילה עבור ישויות
entities
ועצם המהות, שיהיה פרי:
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 +
            '}';
}
}
הקונסטרוקטור, getters, setters ו-toString() אינם חייבים להיכתב ביד; ניתן ליצור אותם במהירות . אוקיי, הישות שלנו מקיימת אינטראקציה עם מסד הנתונים ומאחסנת נתונים ממסד הנתונים. המהות נמצאת בעבודה. אבל מישהו חייב להפעיל את הישות באפליקציה. לשם כך הם הגיעו עם "מאגר". בחבילה
ru.java.rush
יצירת חבילה עבור מאגרים
repositories
והמאגר עצמו
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
}
השאלה היא למה גוף הממשק ריק, אין שיטה אחת שהוא מצהיר? כדי לענות, החזק את Ctrl לחוץ ולחץ על JpaRepository ותראה שהוא עצמו יורש מ-PagingAndSortingRepository<t, ""> ומ-QueryByExampleExecutor<>, הם גם מכריזים על כמה שיטות. אני לא אעתיק את השיטות לכאן; חפש בעצמך. מכיוון שהמאגר הוא ממשק, הוא לא עושה כלום, הוא רק מכריז על שיטות, יש צורך במישהו אחר כדי ליישם את השיטות הללו. זו הסיבה ש"שירות" הומצא. בחבילה
ru.java.rush
יצירת חבילה לשירותים
services
והשירות עצמו
package ru.java.rush.services;

import org.springframework.stereotype.Service;

@Service//помечаем что этот бин - сервис
public class FruitService {
}
כעת הגענו לנקודה חשובה: "איך ולמה להזריק שעועית" (הזרקת תלות). אם אתה לא מבין למה אני מתכוון, אז אני מבקש ממך לקרוא על הנושא הזה, עכשיו או מאוחר יותר, שימו לב במיוחד לשיטות ה"הזרקה", כמה יש, מה עדיף, מה יותר גרוע, ומדוע . אנו משתמשים באחת מהשיטות. אנחנו צריכים שה"שירות" יהיה מחובר איכשהו ל"מאגר". אנו משלימים את השירות שלנו עם ביאור ומשתנה.
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;
}

}
עכשיו אתה יכול ליישם את השיטה מה"מאגר" אנו משלימים את "השירות"
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(); //реализовали метод внедренного бина
    }
}
כל מה שנותר הוא ליישם את זה בכלי השירות שלנו. בואו נעבור למחלקה 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);
        }
    }
}
פלט מסוף: FruitEntity(id=1, fruitName=fruit1, providerCode=1) FruitEntity(id=2, fruitName=fruit2, providerCode=2) FruitEntity(id=3, fruitName=fruit3, providerCode=3) כאן תוכלו לסיים . "רק שניה!" - הקורא הקשוב ביותר יצעק - "היכן נמצא מצב שינה בכלל?" ו-Hibernate פועל כאן כלוחם בחזית הבלתי נראית; הוא עשה דבר חשוב מאוד: הוא יצר עבורנו מבני מסד נתונים. כשכתבנו את השדות ב"ישות" וסימנו אותם בהערות הנדרשות, Hibernate עשתה את עבודתה. למעשה, כאשר מפתחים תוך כדי תנועה, לא סביר שתתעסק במבנה מסד הנתונים; הכל כבר ייווצר וייפרס עבורך. אבל בפרויקטים קטנים כאלה, Hibernate עם היכולת שלו ליצור מבני מסד נתונים פשוט לא ניתנת להחלפה; כמובן שזה לא היתרון היחיד שלה, למשל, היא טובה ביצירת ישויות קשורות (לא נשתמש בהן בפרויקט הזה). נגיד שלום לעובד הצנוע הזה: עבור אל IDEA במבנה הפרויקט (בצד שמאל יש עץ עם תיקיות וקבצים), שם נמצא ספריות חיצוניות, נפתח אותו ונראה בין שאר הספריות
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 הורד עבורנו על ידי Maven ו
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
למעשה, מר היבר ביצע עוד פעולה חשאית, אך על כך נדבר בכתבה הבאה. זה הכל בטוח עכשיו. כתרגיל אימון, אני מציע לך ליישם את שיטת saveAll() עבור FruitEntity בעצמך , שתשמור את כל הישויות במסד הנתונים בבת אחת. לאחר מכן, בואו נסתכל כיצד לקצר את קוד הפרויקט באמצעות ספריית Lombok
הערות
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION