JavaRush /وبلاگ جاوا /Random-FA /بهار ترسناک نیست، یا چگونه یک سوال پایگاه داده بپرسیم
Павел
مرحله

بهار ترسناک نیست، یا چگونه یک سوال پایگاه داده بپرسیم

در گروه منتشر شد
محتویات چرخه مقالات امروز ما در حال نهایی کردن کار با پایگاه داده به عنوان بخشی از پروژه خود هستیم. اگر همه چیز را به درستی انجام داده اید، باید یک پوم با وابستگی های زیر داشته باشید:
<properties>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <java.version>1.8</java.version>
</properties>
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.0.RELEASE</version>
    <relativePath/><!-- lookup parent from repository -->
</parent>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
</dependencies>
و ساختار پروژه این است: بهار ترسناک نیست، یا نحوه پرسیدن سوال پایگاه داده - 1 آیا می دانید چه کسانی را مدتهاست که به یاد نمی آوریم؟ این application.yml است، در یکی از مقالات قبلی زیاد در مورد آن صحبت نکردیم. حالا بیایید جلو برویم و آن را حذف کنیم! بله، بله حذف کنید و تمام! اگر اکنون پروژه را راه اندازی کنیم، همه چیز مانند قبل کار می کند، این را امتحان کنید. این به این دلیل اتفاق افتاد که خود Spring با تنظیمات پیش فرض پیکربندی شده بود. اکنون باید فایل yml خود را به پوشه منابع برگردانیم، همچنان به آن نیاز داریم: application.yml (نام باید یکسان باشد)
spring:
  datasource:
    driverClassName: org.h2.Driver
    url: jdbc:h2:mem:test;
    username: sa
    password:
    h2:
      console:
        enabled: true
  jpa:
    hibernate.ddl-auto: create
    generate-ddl: true
    show-sql: false
    properties:
      hibernate:
        dialect: org.hibernate.dialect.H2Dialect
آخرین بار، چندین پرس و جو را با استفاده از روش های رابط JpaRepository<> در پایگاه داده پیاده سازی کردیم:
//сохранить одну запись в таблицу фруктов
public void save(FruitEntity fruitEntity){
    fruitRepository.save(fruitEntity);
}
//получить все записи из таблицы фруктов
public List<FruitEntity> getAll(){
   return fruitRepository.findAll();
}
//сохранить несколько записей в таблицу фруктов
public void saveAll(List<FruitEntity> fruits){
    fruitRepository.saveAll(fruits);
}
اگر در مورد SQL خوانده اید ، همانطور که دفعه قبل از شما خواسته بودم انجام دهید، باید بدانید که چنین اقداماتی با پایگاه داده باید با استفاده از پرس و جوهای SQL انجام شود. اما هیچ اشاره ای به این موضوع در پروژه وجود ندارد؛ حتی در لاگ های کنسول نیز چیزی مشابه وجود ندارد. بیایید آنها را پیدا کنیم، application.yml را باز کنیم، خط show-sql: را در آنجا پیدا کنیم (sql را نشان دهیم) و false را به true تغییر دهیم. ما پروژه را راه اندازی می کنیم و به کنسول نگاه می کنیم، گزارش ها با ورودی های جدید بسیار شبیه به SQL پر شده است، در واقع درک بیشتر آنها دشوار نیست، به عنوان مثال:
Hibernate: drop table fruit_table if exists //удалить таблицу fruit_table  если она есть
Hibernate: drop table provider_table if exists
Hibernate: create table fruit_table (id_fruit integer not null, fruit_name varchar(255), provider_code integer, primary key (id_fruit))//создать таблицу fruit_table с полями id_fruit тип integer not null, fruit_name  тип varchar(255), provider_code тип integer, назначить первичным ключем поле id_fruit
Hibernate: create table provider_table (id_provider integer not null, provider_name varchar(255), primary key (id_provider))
اما این مدخل ممکن است سوالات زیادی را به دلیل علامت سوالی که دارد ایجاد کند:
Hibernate: insert into fruit_table (fruit_name, provider_code, id_fruit) values (?, ?, ?)
بیایید منطقی فکر کنیم: اولاً کلمه Hibernate را می بینیم که به این معنی است که این مرد مخفی پنجه پشمالو خود را اینجا گذاشته است. پس از خواندن در مورد او در اینترنت، متوجه می شویم که آقای Hiber یک پیاده سازی از مدل ORM است. مدل شی-رابطه ای روابط بین اشیاء نرم افزار و رکوردهای موجود در پایگاه داده را توصیف می کند. پس از رفع این ایده، ما همچنان به منطقی فکر می کنیم: از یک طرف، یک شی FruitEntity داریم ، آن سه فیلد دارد: Integer id; نام میوه رشته; کد ارائه دهنده عدد صحیح از طرف دیگر، جدولی در پایگاه داده fruit_table با فیلدهای id_fruit type integer، fruit_name type varchar(255) ، provider_code type integer داریم . به طور کلی، Hibernate یک شی FruitEntity را می گیرد ، مقادیر فیلدهای شی را بیرون می آورد و آنها را در فیلدهای جدول مربوطه می نویسد. من یک سوال از شما دارم: ببینید، در کلاس InitiateUtils ما پر کردن جدول میوه را پیاده سازی کردیم، اما به دلایلی مقدار را فقط روی دو فیلد قرار دادیم، سومی کجاست؟
new FruitEntity()
        .setFruitName("Fruit1")//раз
        .setProviderCode(Math.abs(new Random().nextInt() % 10)),//два
                                            //три???
من مطمئن هستم که شما خودتان متوجه این موضوع خواهید شد، علاوه بر این، ما در مقاله قبل به طور خلاصه به این موضوع پرداختیم. ابتدا بفهمید کدام رشته اینجا نیست و بعد همه چیز را خواهید فهمید. خوب، آفرین، هایبر تعداد زیادی درخواست برای ما ایجاد کرد. اما ما کور نیستیم، اجازه دهید چند روش دیگر از رابط JpaRepository<> در کلاس FruitService پیاده سازی کنیم.
//возвращает запись из таблицы по id
public Optional<FruitEntity> getById(Integer id){
   return fruitRepository.findById(id);
}

//удаляет запись из таблицы по id
public void delById(Integer id){
    fruitRepository.deleteById(id);
}

//возвращает true or false при поиске в таблице Фруктов an object который соответствует типу FruitEntity or принадлежит к типу an object который наследуется от FruitEntity
public Boolean exist(Example<? extends FruitEntity> example){
    return fruitRepository.exists(example);
}
همین روش ها را در کلاس ProviderService پیاده سازی کنید. سپس از آنها در کلاس InitiateUtils برای FruitEntity و ProviderEntity استفاده کنید و نتیجه را در کنسول چاپ کنید. (در ضمن، اگر نمی دانستید، می توانید با تایپ sout و فشردن enter به سرعت "System.out.println()" بنویسید، همین مورد با "public static void main(String[] args) کار می کند{} "فقط psvm را تایپ کنید و به آنجا بروید و غیره ). من فکر می کنم شما قبلاً این کار را انجام داده اید و ما آماده هستیم که ادامه دهیم. بیایید به رابط FruitRepository برویم و شروع به تایپ کردن در آن کنیم (یعنی تایپ کردن و کپی نکردن) روش زیر: List<FruitEntity> f باید مورد زیر را دریافت کنید.فقط بهار ترسناک نیست، یا نحوه پرسیدن سوال از پایگاه داده - 2 روش را طوری فراخوانی کنید که انگار در حال نوشتن یک پرس و جو هستید: findById(Integer id ) - یک شی را با شناسه پیدا می کند. countFruitEntityByFruitName (نام رشته) - تعداد میوه ها را با یک نام خاص می شمارد. اینها پرس و جوهایی هستند که با نام متد ایجاد می شوند؛ حتماً در مورد آنها مطالعه کنید و متد بین (Integer from, Integer to) را در کلاس FruitService برای جستجوی List<FruitEntity> با مقادیر فیلد provider_code موجود در پیاده سازی کنید. یک فاصله زمانی مشخص، و نتیجه کار را در کنسول نمایش دهید. به عنوان مثال: تمام میوه هایی را که تعداد عرضه کننده آنها بین 5 تا 7 است را پیدا کنید. تا زمانی که روش را اجرا نکنید برای خواندن ادامه مطلب عجله نکنید، زیاد طول نمی کشد. همانطور که ممکن است در مقاله در مورد کوئری ها بر اساس نام روش خوانده باشید: "شما نمی توانید همه پرس و جوها را به این صورت بنویسید، اما موارد ساده را می توان نوشت." برای پرس و جوهای پیچیده تر، از حاشیه نویسی @Query استفاده می شود و از JPQL به جای SQL استفاده می شود (این مقاله را نیز در نظر داشته باشید).
package ru.java.rush.repositories;

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

import java.util.List;

@Repository
public interface FruitRepository extends JpaRepository<FruitEntity,Integer> {

    @Query("select f.fruitName, p.providerName from  FruitEntity f left join ProviderEntity p on f.providerCode = p.id")
    List<String> joinSting();

}
یک پرس و جو استاندارد SQL این خواهد بود: "select fruit_table.fruit_name, provider_table.provider_name از fruit_table سمت چپ join provider_table در fruit_table.provider_code = provider_table.id". در اینجا می توانید به راحتی یک مکاتبه ایجاد کنید: f ruit_table FruitEntiy f است که در آن FruitEntiy نوع متغیر است، f نام آن است، یعنی SQL با جداول و فیلدها کار می کند و JPQL با اشیا و فیلدهای آنها. دوباره fruit_table.fruit_name f.fruitName است . از آنجایی که ما با اشیا کار می کنیم، می توانیم آبجکت را خروجی بگیریم: بیایید یک متد FruitRepository دیگر بنویسیم
@Query("select f from  FruitEntity f  join ProviderEntity p on f.providerCode = p.id")
List<FruitEntity> joinFruit();
بیایید هر دو روش را در کلاس FruitService پیاده سازی کنیم
public List<String> joinString(){
   return fruitRepository.joinSting();
}

public List<FruitEntity> joinFruit(){
    return fruitRepository.joinFruit();
}
بد به نظر نمی رسد، اما آنها همچنان از SQL قدیمی خوب برای پرس و جوهای پیچیده استفاده می کنند
@Query(
        value = "select fruit_table.fruit_name, provider_table.provider_name from  fruit_table  join provider_table on fruit_table.provider_code = provider_table.id_provider",  //по идее эту портянку надо засунуть в Howой нибудь  Enum
        nativeQuery = true) //нужно только пометить только nativeQuery = true
ListList<String> joinSqlFruit();
و ما از همه آنها در کلاس InitiateUtils استفاده می کنیم
System.out.println("\nТаблица фруктов и их поставщиков");
for (String join : fruitService.joinString()) {
    System.out.println(join);
}

System.out.println("\nТаблица фруктов и их поставщиков");
for (FruitEntity join : fruitService.joinFruit()) {
    System.out.println(join);
}

System.out.println("\nТаблица фруктов и их поставщиков");
        for (String join : fruitService.joinSqlFruit()) {
            System.out.println(join);
        }
ما پروژه را راه‌اندازی می‌کنیم و گزارش‌های جدیدی را در کنسول می‌بینیم: جدول میوه‌ها و تامین‌کنندگان آن‌ها Fruit1، Null Fruit2، Provider5 Fruit3، Provider2 Fruit4، Provider5 Fruit5، Null Fruit6، Null Fruit7، Null Fruit8، Null Fruit9، جدول میوه‌های تهی آنها تامین کنندگان FruitEntity(id= 2, fruitName=Fruit2, providerCode=5) FruitEntity(id=3, fruitName=Fruit3, providerCode=2) FruitEntity(id=4, fruitName=Fruit4, providerCode=5) جدول تامین کنندگان میوه ها و آنها ,Provider5 Fruit3,Provider2 Fruit4,Provider5 بله، اگر قبلاً از "شبه" و فقط پرس و جوهای SQL در کنسول خسته شده اید، می توانید false را در جای خود در فایل yaml برگردانید. چرا در جدول اول null وجود دارد، اگر در مورد JOIN SQL بخوانید متوجه خواهید شد . و بنابراین، ما با پرس و جوهای پایگاه داده تمام شدیم، من مطمئن هستم که شما هنوز سوالات زیادی دارید، اما امیدوارم که به دنبال پاسخ آنها باشید، من سعی کردم مسیرهای جستجو را برجسته کنم. بیایید سعی کنیم همه چیزهایی را که در این مدت یاد گرفتیم خلاصه کنیم: 1. شما می توانید یک وب سرور را در بهار اجرا کنید و کار سختی نیست. 2. برای اینکه بفهمید همه اینها چگونه کار می کند، باید در تئوری فرو بروید. درباره کتاب مقاله در مورد بهار مقاله در مورد چیزهای مفید 3. برای اینکه درک به کد فیزیکی تبدیل شود، باید کدنویسی کنید و قبل از حرکت به پروژه های ساده روی فنر بوت دست پیدا کنید. و بهتر است کد نوشته شده را کپی نکنید، بلکه آن را بازنویسی کنید. پروژه ای که من و شما روی آن کار کرده ایم را اینجا پست می کنم، اما به آگاهی شما تکیه می کنم و مطمئن هستم که بی خیال کپی پیست نمی کنید. پیوند به مخزن git clone https://FromJava@bitbucket.org/FromJava/jd.git برای کسانی که نحوه استفاده از این لینک را نمی دانند، اجرای دو پروژه آموزشی را توصیه می کنم: پروژه نقاشی ماشین: درجه یک: CarEntity{ Integer شناسه؛ رشته نام مدل; رنگ رشته؛ } کلاس دوم: ColorEntity{ Integer id; رنگ رشته؛ قیمت عدد صحیح؛ } پایگاه داده را پر کنید (اسامی واقعی بیاورید تا درک آن آسان تر شود)، پیاده سازی کنید: , نهاد، مخازن، خدمات، ایجاد پرسش های استاندارد و جداول متقاطع (هزینه رنگ آمیزی یک BMW قرمز چقدر است؟ چه رنگی است؟ گران‌ترین مدل‌ها را به ترتیب حروف الفبا و غیره روی کنسول بنویسید. پروژه کتابخانه: First class: BookEntity{ Integer id; رشته نام کتاب; عدد صحیح yearCreat; autorId عدد صحیح } Second class: AutorEntity{ Integer id; رشته firstNameAutor; رشته lastNameAutor; } پایگاه داده را پر کنید (اسامی واقعی بیاورید تا درک آن آسان تر شود)، پیاده سازی کنید: موجودیت، مخازن، خدمات، ایجاد پرس و جوهای استاندارد و بین جداول (چه کسی کدام کتاب را نوشته است؟ کدام کتاب اول نوشته شده است؟ کدام کتاب نوشته شده است. از 1800 تا 1900 کدام یک از نویسندگان بیشترین کتاب را نوشتند؟) نمونه هایی برای پر کردن پایگاه داده پروژه "کتابخانه". جدول کتاب BookEntity(id=1، nameBook=وای از هوش، yearCreat=1824، authorId=1) BookEntity(id=2، nameBook=War and Peace، yearCreat=1863، authorId=2) BookEntity(id=3، nameBook= Mtsyri, yearCreat=1838, authorId=3) BookEntity(id=4, nameBook=Eugene Onegin, yearCreat=1833, authorId=4) جدول نویسنده AuthorEntity(id=1, firstNameAuthor=Alexander, lastNameAuthor=Griboedity(2) Author=Author ، firstNameAuthor=Lev، lastNameAuthor=تولستوی) AuthorEntity(id=3، firstNameAuthor=میخائیل، lastNameAuthor=Lermontov) AuthorEntity(id=4، firstNameAuthor=اسکندر، lastNameAuthor دوباره همه را خوب می بینید، پوشکین!
نظرات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION