JavaRush /Java Blogu /Random-AZ /Bahar qorxulu deyil və ya verilənlər bazası sualını necə ...
Павел
Səviyyə

Bahar qorxulu deyil və ya verilənlər bazası sualını necə vermək olar

Qrupda dərc edilmişdir
MƏQALƏLƏR DÖVRÜNÜN MÜNDƏRİCASI Bu gün biz layihəmizin bir hissəsi kimi verilənlər bazası ilə işi yekunlaşdırırıq. Hər şeyi düzgün etmisinizsə, onda aşağıdakı asılılıqları olan bir pom olmalıdır:
<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>
Layihənin strukturu isə budur: Bahar qorxulu deyil və ya verilənlər bazası sualını necə vermək olar - 1 Uzun müddətdir kimə yadımızda qalmadığımızı bilirsinizmi? Bu application.yml-dir, əvvəlki məqalələrin birində bu haqda çox danışmadıq. İndi davam edək və onu silək! Bəli, bəli silin və bu qədər! Layihəni indi işə salsaq, hər şey əvvəlki kimi işləyəcək, bunu sınayın. Bu, Baharın özü standart parametrlərlə konfiqurasiya edildiyi üçün baş verdi. İndi yml faylımızı yenidən resurslar qovluğuna qaytarmalıyıq, bizə hələ də lazım olacaq: application.yml (ad eyni olmalıdır)
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
Keçən dəfə biz JpaRepository<> interfeysinin metodlarından istifadə etməklə verilənlər bazasına bir neçə sorğu həyata keçirdik:
//сохранить одну запись в таблицу фруктов
public void save(FruitEntity fruitEntity){
    fruitRepository.save(fruitEntity);
}
//получить все записи из таблицы фруктов
public List<FruitEntity> getAll(){
   return fruitRepository.findAll();
}
//сохранить несколько записей в таблицу фруктов
public void saveAll(List<FruitEntity> fruits){
    fruitRepository.saveAll(fruits);
}
Keçən dəfə sizdən xahiş etdiyim kimi SQL haqqında oxuyursunuzsa , o zaman bilməlisiniz ki, verilənlər bazası ilə bu cür hərəkətlər SQL sorğularından istifadə etməklə həyata keçirilməlidir. Ancaq layihədə bunun heç bir işarəsi yoxdur, hətta konsol qeydlərində belə bir şey yoxdur. Gəlin onları tapaq, application.yml-i açın, orada show-sql: sətrini tapın (show sql) və false-i doğruya dəyişin. Layihəni işə salırıq və konsola baxırıq, qeydlər SQL-ə çox oxşar yeni girişlərlə doludur, əslində onların əksəriyyətini başa düşmək çətin deyil, məsələn:
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))
Lakin bu giriş sual işarələrinə görə çoxlu suallar yarada bilər:
Hibernate: insert into fruit_table (fruit_name, provider_code, id_fruit) values (?, ?, ?)
Gəlin məntiqlə düşünək: Birincisi, Hibernate sözünü görürük, yəni bu gizli oğlan tüklü pəncəsini bura qoyub. İnternetdə onun haqqında oxuduqdan sonra cənab Hiberin ORM modelinin tətbiqi olduğunu öyrənirik. Obyekt-əlaqəli model proqram obyektləri və verilənlər bazasındakı qeydlər arasındakı əlaqələri təsvir edir. Bu fikri düzəldərək məntiqi düşünməyə davam edirik: Bir tərəfdən FruitEntity obyektimiz var , onun üç sahəsi var: Tam ədəd id; String fruitName; Tam provayder kodu. Digər tərəfdən, id_fruit type integer, fruit_name type varchar(255) , provider_code type integer sahələri olan fruit_table verilənlər bazasında cədvəlimiz var. Təxminən desək, Hibernate FruitEntity obyektini götürür , obyektin sahələrinin dəyərlərini çıxarır və onları müvafiq cədvəl sahələrinə yazır. Sizə sualım var: Baxın, InitiateUtils sinfində biz meyvə cədvəlinin doldurulmasını həyata keçirdik, amma nədənsə dəyəri yalnız iki sahəyə təyin etdik, üçüncü haradadır?
new FruitEntity()
        .setFruitName("Fruit1")//раз
        .setProviderCode(Math.abs(new Random().nextInt() % 10)),//два
                                            //три???
Əminəm ki, bunu özünüz başa düşəcəksiniz, üstəlik, sonuncu məqalədə bu məsələyə qısaca toxunmuşuq. Əvvəlcə hansı sahənin burada olmadığını müəyyənləşdirin, sonra hər şeyi başa düşəcəksiniz. Yaxşı, Hiber bizim üçün çoxlu sorğular yaratdı. Ancaq biz kor deyilik, FruitService sinfində JpaRepository<> interfeysindən bir neçə daha metod tətbiq edək.
//возвращает запись из таблицы по 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 sinfində eyni metodları tətbiq edin. Sonra onları FruitEntityProviderEntity üçün InitiateUtils sinfində istifadə edin və nəticəni konsolda çap edin. (Yeri gəlmişkən, əgər bilmirsinizsə, sout yazıb enter düyməsini sıxmaqla “System.out.println()” yaza bilərsiniz, eyni şey “public static void main(String[] args){} ilə işləyir. ” sadəcə olaraq psvm yazın və orada gedirsiniz və s. ). Düşünürəm ki, siz artıq bununla məşğul olmusunuz və biz davam etməyə hazırıq. Gəlin FruitRepository interfeysinə keçək və onda aşağıdakı metodu yazmağa başlayaq (yəni yazın və kopyalamayın): List<FruitEntity> f Aşağıdakı şeyi əldə etməlisiniz.Sadəcə metodu sorğu tərtib edirmiş kimi çağırın: findById(Integer id ) - obyekti id ilə tapır; countFruitEntityByFruitName(String name) - müəyyən bir adla meyvələrin sayını hesablayacaq; Bunlar metodun adı ilə yaradılan sorğulardır; onlar haqqında oxuduğunuzdan əmin olun və FruitService sinfində (Integer from, Integer to) arasında metodu tətbiq edin və List<FruitEntity>-də daxil edilmiş provayder_kodu sahəsinin dəyərləri ilə axtarış edin. müəyyən bir interval və işin nəticəsini konsolda göstərin. Məsələn: tədarükçünün nömrəsi 5 ilə 7 arasında olan bütün meyvələri tapın. Metodunu həyata keçirənə qədər daha çox oxumağa tələsməyin, bu çox çəkməyəcək. Metod adı ilə sorğular haqqında məqalədə oxumuş ola bilərsiniz: "Bütün sorğuları belə yaza bilməzsiniz, lakin sadə olanlar yazıla bilər." Daha mürəkkəb sorğular üçün @Query annotasiyası istifadə olunur və SQL əvəzinə JPQL istifadə olunur (həmçinin bu məqaləni qeyd edin). Layihəmiz üçün JOIN sorğuları edə bilərsiniz, məsələn: Bahar qorxulu deyil və ya verilənlər bazası sualını necə vermək olar - 2
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();

}
Standart SQL sorğusu belə olardı: "fruit_table.fruit_name, provider_table.provider_name-dən fruit_table-dan provayder_table.provider_name sol birləşin fruit_table.provider_code = provider_table.id". Burada siz asanlıqla yazışma qura bilərsiniz: f ruit_table FruitEntiy f, burada FruitEntiy dəyişənin növüdür, f onun adıdır, yəni SQL cədvəllər və sahələrlə, JPQL isə obyektlər və onların sahələri ilə işləyir. Yenə fruit_table.fruit_name f.fruitName ; _ Obyektlərlə işlədiyimiz üçün obyekti çıxara bilərik: Gəlin başqa bir FruitRepository metodunu yazaq
@Query("select f from  FruitEntity f  join ProviderEntity p on f.providerCode = p.id")
List<FruitEntity> joinFruit();
Gəlin hər iki üsulu FruitService sinfində tətbiq edək
public List<String> joinString(){
   return fruitRepository.joinSting();
}

public List<FruitEntity> joinFruit(){
    return fruitRepository.joinFruit();
}
Pis səslənmir, lakin onlar hələ də mürəkkəb sorğular üçün yaxşı köhnə SQL-dən istifadə edirlər
@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();
Və biz onların hamısını InitiateUtils sinfində istifadə edirik
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);
        }
Biz layihəni işə salırıq və konsolda yeni qeydləri görürük: Meyvələr və onların tədarükçüləri Cədvəli Meyvə1,null Meyvə2,Provayder5 Meyvə3,Provider2 Meyvə4,Provider5 Meyvə5,null Meyvə6,null Meyvə7,null Meyvə8,null Meyvə9,null Meyvə Cədvəli təchizatçılar FruitEntity(id= 2, fruitName=Fruit2, providerCode=5) FruitEntity(id=3, fruitName=Fruit3, providerCode=2) FruitEntity(id=4, fruitName=Fruit4, providerCode=5) Cədvəl meyvələr və onların təchizatçıları Meyvə2 ,Provider5 Fruit3,Provider2 Fruit4 ,Provider5 Bəli, əgər siz artıq “psevdo” və konsolda sadəcə SQL sorğularından bezmisinizsə, yaml faylında false yerinə qaytara bilərsiniz. Birinci cədvəldə niyə null var, JOIN SQL haqqında oxusanız öyrənəcəksiniz . Və beləliklə, verilənlər bazasına sorğularla tamamlandıq, əminəm ki, hələ də çoxlu suallarınız var, amma ümid edirəm ki, onlara cavab axtaracaqsınız, axtarış yollarını vurğulamağa çalışdım. Bu müddət ərzində öyrəndiyimiz hər şeyi ümumiləşdirməyə çalışaq: 1. Baharda veb server işlədə bilərsiniz və bu, çətin deyil. 2. Bütün bunların necə işlədiyini başa düşmək üçün nəzəriyyəyə dalmaq lazımdır. Kitab haqqında Bahar haqqında məqalə Faydalı şeylər haqqında məqalə 3. Anlayışın fiziki koda çevrilməsi üçün kodlaşdırmalısan və davam etməzdən əvvəl yaz-bootda sadə layihələrə əl atmalısan. Yazılı kodu kopyalamamaq, yenidən yazmaq daha yaxşıdır. Sizin və mənim üzərində işlədiyimiz layihəni burada yerləşdirəcəyəm, lakin sizin məlumatlılığınıza arxalanacağam və əminəm ki, siz ağılsızcasına kopyala-yapışdırmayacaqsınız. Git klon deposuna keçid https://FromJava@bitbucket.org/FromJava/jd.git Bu linkdən necə istifadə edəcəyini bilməyənlər üçün iki təlim layihəsini həyata keçirməyi məsləhət görürəm: Avtomobillərin rənglənməsi layihəsi: Birinci sinif: CarEntity{ Tam ədəd id; String modelName; sim rəngi; } İkinci sinif: ColorEntity{ Tam ədəd id; sim rəngi; Tam qiymət; } Verilənlər bazasını doldurun (anlaşılması asan olsun deyə real adlar tapın), həyata keçirin: , müəssisə, depolar, xidmətlər, standart və çarpaz cədvəl sorğuları yaradın (BMW-ni qırmızı rəngə boyamaq nə qədər başa gəlir? Hansı rəngdədir? ən bahalı modelləri konsola əlifba sırası ilə yazın və s.); Kitabxana layihəsi: Birinci sinif: BookEntity{ Tam ədəd id; String nameBook; Tam yearCreat; Tam ədədin müəllif identifikatoru; } İkinci sinif: AutorEntity{ Tam ədəd id; String firstNameAutor; String LastNameAutor; } Verilənlər bazasını doldurun (həqiqi adlar tapın ki, başa düşmək asan olsun), həyata keçirin: obyekt, repozitoriyalar, xidmətlər, standart və cədvəllərarası sorğular yaradın (Hansı kitabı kim yazıb? Hansı kitab ilk dəfə yazılıb? Hansı kitablar yazılıb? 1800-cü ildən 1900-cü ilə qədər? Müəlliflərdən hansı daha çox kitab yazmışdır?); "Kitabxana" layihəsi məlumat bazasının doldurulması üçün nümunələr Kitab cədvəli BookEntity(id=1, nameBook=Wit-dən vay, yearCreat=1824, authorId=1) BookEntity(id=2, nameBook=Müharibə və Sülh, yearCreat=1863, authorId=2) BookEntity(id=3, nameBook= Mtsyri, yearCreat=1838, authorId=3) BookEntity(id=4, nameBook=Eugene Onegin, yearCreat=1833, authorId=4) Müəllif cədvəli AuthorEntity(id=1, firstNameAuthor=Alexander, lastNameAuthor=Griboyedov) Aut=2 , firstNameAuthor=Lev, LastNameAuthor=Tolstoy) AuthorEntity(id=3, firstNameAuthor=Mikhail, lastNameAuthor=Lermontov) AuthorEntity(id=4, firstNameAuthor=Alexander, lastNameAuthor=Puşkin) Hər kəsə uğurlar, bir daha görüşənədək
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION