JavaRush /Java blogi /Random-UZ /Bahor qo'rqinchli emas, yoki ma'lumotlar bazasiga qanday ...

Bahor qo'rqinchli emas, yoki ma'lumotlar bazasiga qanday savol berish kerak

Guruhda nashr etilgan
MAQOLALAR SIKLINING MAZMUNI Bugun biz loyihamiz doirasida ma'lumotlar bazasi bilan ishlashni yakunlaymiz. Agar siz hamma narsani to'g'ri bajargan bo'lsangiz, unda siz quyidagi bog'liqliklar bilan pomga ega bo'lishingiz kerak:
<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>
Va bu erda loyihaning tuzilishi: Bahor qo'rqinchli emas yoki ma'lumotlar bazasiga qanday savol berish kerak - 1 Biz kimni uzoq vaqt davomida eslamaganimizni bilasizmi? Bu application.yml, biz avvalgi maqolalarning birida bu haqda ko'p gapirmadik. Keling, uni o'chirib tashlaymiz! Ha, ha, o'chirib tashlang va tamom! Agar biz loyihani hozir ishga tushirsak, hammasi avvalgidek ishlaydi, buni sinab ko'ring. Bu bahorning o'zi standart sozlamalar bilan tuzilganligi sababli sodir bo'ldi. Endi biz yml faylimizni resurslar papkasiga qaytarishimiz kerak, bizga hali kerak bo'ladi: application.yml (nom bir xil bo'lishi kerak)
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
Oxirgi marta biz JpaRepository<> interfeysi usullaridan foydalangan holda ma'lumotlar bazasiga bir nechta so'rovlarni amalga oshirdik:
//сохранить одну запись в таблицу фруктов
public void save(FruitEntity fruitEntity){
    fruitRepository.save(fruitEntity);
}
//получить все записи из таблицы фруктов
public List<FruitEntity> getAll(){
   return fruitRepository.findAll();
}
//сохранить несколько записей в таблицу фруктов
public void saveAll(List<FruitEntity> fruits){
    fruitRepository.saveAll(fruits);
}
Agar siz SQL haqida o'qigan bo'lsangiz, oxirgi marta sizdan so'raganimdek, ma'lumotlar bazasi bilan bunday harakatlar SQL so'rovlari yordamida bajarilishi kerakligini bilishingiz kerak. Ammo loyihada bu haqda hech qanday ishora yo'q, hatto konsol jurnallarida ham shunga o'xshash narsa yo'q. Keling, ularni topamiz, application.yml-ni oching, u erda show-sql: qatorini topamiz (sql-ni ko'rsatish) va false-ni rostga o'zgartiramiz. Biz loyihani ishga tushiramiz va konsolga qaraymiz, jurnallar SQL ga juda o'xshash yangi yozuvlar bilan to'ldirilgan, aslida ularning aksariyatini tushunish qiyin emas, masalan:
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))
Ammo bu yozuv savol belgilari tufayli juda ko'p savollar tug'dirishi mumkin:
Hibernate: insert into fruit_table (fruit_name, provider_code, id_fruit) values (?, ?, ?)
Keling, mantiqan o'ylab ko'raylik: Birinchidan, biz Hibernate so'zini ko'ramiz, ya'ni bu yashirin odam tukli panjasini bu erga qo'ygan. Internetda u haqida o'qiganimizdan so'ng, biz janob Hiber ORM modelini amalga oshirish ekanligini bilib olamiz. Ob'ektga aloqador model dasturiy ta'minot ob'ektlari va ma'lumotlar bazasidagi yozuvlar o'rtasidagi munosabatlarni tavsiflaydi. Ushbu g'oyani tuzatib, biz mantiqiy fikrlashni davom ettiramiz: Bir tomondan, bizda FruitEntity ob'ekti bor , u uchta maydonga ega: Integer id; String fruitName; Butun son provayder kodi. Boshqa tomondan, bizda fruit_table ma'lumotlar bazasida id_fruit type integer, fruit_name type varchar(255) , provider_code type integer maydonlari mavjud jadval mavjud. Taxminan aytganda, Hibernate FruitEntity ob'ektini oladi , ob'ekt maydonlarining qiymatlarini chiqaradi va ularni tegishli jadval maydonlariga yozadi. Sizga savolim bor: Qarang, InitiateUtils sinfida biz meva jadvalini to'ldirishni amalga oshirdik, lekin negadir biz qiymatni faqat ikkita maydonga o'rnatdik, uchinchisi qayerda?
new FruitEntity()
        .setFruitName("Fruit1")//раз
        .setProviderCode(Math.abs(new Random().nextInt() % 10)),//два
                                            //три???
Ishonchim komilki, siz buni o'zingiz tushunasiz, bundan tashqari, biz oxirgi maqolada bu masalaga qisqacha to'xtalib o'tdik. Birinchidan, bu erda qaysi soha yo'qligini aniqlang, keyin hamma narsani tushunasiz. Yaxshi, Xiber biz uchun bir qancha soʻrovlarni yaratdi. Ammo biz ko'r emasmiz, keling, FruitService sinfidagi JpaRepository<> interfeysidan yana bir nechta usullarni amalga oshiramiz.
//возвращает запись из таблицы по 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 sinfida bir xil usullarni qo'llang. Keyin ularni FruitEntity va ProviderEntity uchun InitiateUtils sinfida foydalaning va natijani konsolga chop eting. (Aytgancha, agar siz bilmagan bo'lsangiz, sout ni yozib, enter tugmasini bosish orqali "System.out.println()" ni tezda yozishingiz mumkin, xuddi shu narsa "public static void main(String[] args){} bilan ishlaydi. ” shunchaki psvm yozing va u erga boring va hokazo ). O'ylaymanki, siz buni allaqachon hal qildingiz va biz davom etishga tayyormiz. Keling, FruitRepository interfeysiga o'tamiz va unda quyidagi usulni yozishni boshlaymiz (ya'ni terish va nusxa ko'chirish emas): List<FruitEntity> f Siz quyidagi narsani olishingiz kerak.Usulni xuddi so'rov tuzayotgandek chaqiring: findById(Integer id ) - id bo'yicha ob'ektni topadi; countFruitEntityByFruitName(String nomi) - ma'lum bir nomga ega bo'lgan mevalar sonini sanaydi; Bu usul nomi bilan yaratilgan so'rovlardir; ular haqida o'qing va FruitService sinfidagi (Integer from, Integer to) o'rtasidagi (Integer from, Integer to) usulini o'z ichiga olgan provayder_kodi maydonining qiymatlari bo'yicha List<FruitEntity> qidirishni amalga oshiring. ma'lum bir oraliq va konsolda ish natijasini ko'rsatish. Misol uchun: yetkazib beruvchi raqami 5 dan 7 gacha bo'lgan barcha mevalarni toping. Usulni amalga oshirmaguningizcha keyingi o'qishga shoshilmang, bu ko'p vaqt talab qilmaydi. Usul nomi bo'yicha so'rovlar haqidagi maqolada o'qigan bo'lishingiz mumkin: "Siz barcha so'rovlarni bunday yozishingiz mumkin emas, lekin oddiy so'rovlarni yozishingiz mumkin." Murakkab so'rovlar uchun @Query izohi va SQL o'rniga JPQL ishlatiladi (shuningdek, ushbu maqolaga e'tibor bering). Loyihamiz uchun JOIN so'rovlarini quyidagicha qilishingiz mumkin: Bahor qo'rqinchli emas, yoki ma'lumotlar bazasiga qanday savol berish kerak - 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 so'rovi quyidagicha bo'ladi: "fruit_table.fruit_name, provider_table.provider_name ni fruit_table chap qo'shiling provayder_table on fruit_table.provider_code = provider_table.id". Bu yerda siz osongina yozishmalarni o'rnatishingiz mumkin: f ruit_table - FruitEntiy f, bu erda FruitEntiy - o'zgaruvchining turi, f - uning nomi, ya'ni SQL jadvallar va maydonlar bilan, JPQL esa ob'ektlar va ularning maydonlari bilan ishlaydi. Yana fruit_table.fruit_name f.fruitName ; _ Ob'ektlar bilan ishlaganimiz uchun biz ob'ektni chiqarishimiz mumkin: Keling, boshqa FruitRepository usulini yozaylik
@Query("select f from  FruitEntity f  join ProviderEntity p on f.providerCode = p.id")
List<FruitEntity> joinFruit();
Keling, FruitService sinfida ikkala usulni ham amalga oshiramiz
public List<String> joinString(){
   return fruitRepository.joinSting();
}

public List<FruitEntity> joinFruit(){
    return fruitRepository.joinFruit();
}
Bu yomon ko'rinmaydi, lekin ular hali ham murakkab so'rovlar uchun yaxshi eski SQL-dan foydalanadilar
@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();
Va biz ularning barchasini InitiateUtils sinfida ishlatamiz
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 loyihani ishga tushiramiz va konsolda yangi jurnallarni ko'ramiz: Mevalar va ularning yetkazib beruvchilari jadvali Fruit1,null Fruit2, Provider5 Fruit3, Provider2 Fruit4, Provider5 Fruit5, null Fruit6, null Fruit7, null Fruit8, null Fruit9, null Mevalar jadvali yetkazib beruvchilar FruitEntity(id=2, fruitName=Fruit2, providerCode=5) FruitEntity(id=3, fruitName=Fruit3, providerCode=2) FruitEntity(id=4, fruitName=Fruit4, providerCode=5) Mevalar va ularning yetkazib beruvchilari Meva2 ,Provider5 Fruit3,Provider2 Fruit4 ,Provider5 Ha, agar siz allaqachon konsoldagi “pseudo” va shunchaki SQL so‘rovlaridan charchagan bo‘lsangiz, yaml faylidagi o‘rniga “false”ni qaytarishingiz mumkin. Nima uchun birinchi jadvalda null bor, JOIN SQL haqida o'qigan bo'lsangiz, bilib olasiz . Shunday qilib, biz ma'lumotlar bazasiga so'rovlar bilan yakunlandik, men sizda hali ko'p savollaringiz borligiga aminman, lekin umid qilamanki, siz ularga javob izlaysiz, men qidiruv yo'llarini ta'kidlashga harakat qildim. Keling, shu vaqt ichida o'rganganlarimizni umumlashtirishga harakat qilaylik: 1. Bahorda veb-serverni ishga tushirishingiz mumkin va bu qiyin emas. 2. Bularning barchasi qanday ishlashini tushunish uchun siz nazariyaga sho'ng'ishingiz kerak. Kitob haqida Bahor haqida maqola Foydali narsalar haqida maqola 3. Tushunish jismoniy kodga aylanishi uchun siz kodlashingiz kerak va davom etishdan oldin bahor-bootdagi oddiy loyihalar bilan tanishib chiqing. Va yozma kodni nusxalash emas, balki uni qayta yozish yaxshiroqdir. Men siz va men ustida ishlagan loyihani shu yerda joylashtiraman, lekin men sizning xabardorligingizga tayanaman va ishonchim komilki, siz o'ylamasdan nusxa ko'chirmaysiz. Git klon omboriga havola https://FromJava@bitbucket.org/FromJava/jd.git Ushbu havoladan qanday foydalanishni bilmaganlar uchun ikkita o'quv loyihasini amalga oshirishni tavsiya qilaman: Avtomobillarni bo'yash loyihasi: Birinchi sinf: CarEntity{ Integer id; String modelName; Ip rangi; } Ikkinchi sinf: ColorEntity{ Integer id; Ip rangi; Butun qiymat; } Ma'lumotlar bazasini to'ldiring (tushunish osonroq bo'lishi uchun haqiqiy nomlar bilan chiqing), amalga oshiring: , ob'ekt, omborlar, xizmatlar, standart va o'zaro jadval so'rovlarini yarating (BMW ni qizil rangga bo'yash qancha turadi? Qanday rang eng qimmatmi konsolga modellarni alifbo tartibida yozing va hokazo); Kutubxona loyihasi: Birinchi sinf: BookEntity{ Integer id; String nameBook; Butun son yearCreat; Integer autorId; } Ikkinchi sinf: AutorEntity{ Integer id; String firstNameAutor; String lastNameAutor; } Ma’lumotlar bazasini to‘ldiring (tushunish oson bo‘lishi uchun real nomlar keltiring), amalga oshiring: ob’ekt, omborlar, xizmatlar, standart va jadvallararo so‘rovlarni yarating (Kim qaysi kitobni yozgan? Qaysi kitob birinchi bo‘lib yozilgan? Qaysi kitoblar yozilgan? 1800 yildan 1900 yilgacha qaysi muallif eng ko'p kitob yozgan?); "Kutubxona" loyihasi ma'lumotlar bazasini to'ldirishga misollar Kitob jadvali BookEntity(id=1, nameBook=Witdan voy, yearCreat=1824, authorId=1) BookEntity(id=2, nameBook=Urush va Tinchlik, yearCreat=1863, authorId=2) BookEntity(id=3, nameBook= Mtsyri, yearCreat=1838, authorId=3) BookEntity(id=4, nameBook=Eugene Onegin, yearCreat=1833, authorId=4) Mualliflar jadvali AuthorEntity(id=1, firstNameAuthor=Alexander, lastNameAuthor=Griboyedov) Aut=2 , firstNameAuthor=Lev, lastNameAuthor=Tolstoy) AuthorEntity(id=3, firstNameAuthor=Mikhail, lastNameAuthor=Lermontov) AuthorEntity(id=4, firstNameAuthor=Aleksandr, lastNameAuthor=Pushkin) Hammaga omad ! Yana ko'rishguncha
Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION