JavaRush /Java блогы /Random-KK /Көктем қорқынышты емес немесе дерекқорға сұрақ қою
Павел
Деңгей

Көктем қорқынышты емес немесе дерекқорға сұрақ қою

Топта жарияланған
МАҚАЛАЛАР ЦИКЛІНІҢ МАЗМҰНЫ Бүгін біз жоба аясында деректер қорымен жұмысты аяқтаймыз. Егер сіз бәрін дұрыс жасасаңыз, сізде келесі тәуелділіктер бар пом болуы керек:
<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, біз бұл туралы алдыңғы мақалалардың бірінде көп айтқан жоқпыз. Енді оны жойып жіберейік! Иә, иә, жойыңыз және солай! Егер біз жобаны қазір іске қоссақ, бәрі бұрынғыдай жұмыс істейді, мынаны көріңіз. Бұл көктемнің өзі әдепкі параметрлермен конфигурацияланғандықтан болды. Енді біз 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 көрсету) және жалғанды ​​шынға өзгертіңіз. Біз жобаны іске қосып, консольге қараймыз, журналдар 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 (?, ?, ?)
Логикалық ойланайық: Біріншіден, біз бұл жасырын жігіттің түкті табанын осында қойғанын білдіретін Күту сөзін көреміз. Интернетте ол туралы оқығаннан кейін, біз Гибер мырзаның ORM үлгісін іске асыру екенін білеміз. Объектілік реляциялық модель программалық an objectілер мен деректер қорындағы жазбалар арасындағы байланыстарды сипаттайды. Бұл идеяны бекітіп, біз логикалық ойлауды жалғастырамыз: Бір жағынан, бізде FruitEntity нысаны бар , оның үш өрісі бар: Integer id; String fruitName; Бүтін провайдер codeы. Екінші жағынан, бізде fruit_table дерекқорында id_fruit типті бүтін сан, fruit_name түрі varchar(255) , provider_code типті бүтін өрістері бар кесте бар. Шамамен айтқанда, Hibernate FruitEntity нысанын алады , нысан өрістерінің мәндерін шығарады және оларды сәйкес кесте өрістеріне жазады. Менің сізге сұрағым бар: Қараңызшы, InitiateUtils класында біз жемістер кестесін толтыруды жүзеге асырдық, бірақ қандай да бір себептермен мәнді тек екі өріске орнаттық, үшінші қайда?
new FruitEntity()
        .setFruitName("Fruit1")//раз
        .setProviderCode(Math.abs(new Random().nextInt() % 10)),//два
                                            //три???
Сіз мұны өзіңіз анықтайтыныңызға сенімдімін, сонымен қатар біз соңғы мақалада бұл мәселеге қысқаша тоқталған болатынбыз. Алдымен бұл жерде қай өріс жоқ екенін анықтаңыз, содан кейін бәрін түсінесіз. Жарайсың, Хибер бізге көптеген сұраулар жасады. Бірақ біз соқыр емеспіз, FruitService класындағы JpaRepository<> интерфейсінен тағы бірнеше әдісті енгізейік.
//возвращает запись из таблицы по 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 сыныбында бірдей әдістерді енгізіңіз. Содан кейін оларды FruitEntity және ProviderEntity үшін InitiateUtils сыныбында пайдаланыңыз және нәтижені консольге басып шығарыңыз. (Айтпақшы, егер білмесеңіз, sout деп теріп, enter пернесін басу арқылы «System.out.println()» жылдам жазуға болады, дәл солай «public static void main(String[] args){} ” жай ғана psvm деп теріңіз, сонда сіз т.б. ). Менің ойымша, сіз мұны жасадыңыз және біз әрі қарай жүруге дайынбыз. FruitRepository интерфейсіне өтіп , оған келесі әдіспен теруді бастайық (яғни теру және көшірмеу): List<FruitEntity> f Сіз келесі нәрсені алуыңыз керек. Тек сұрауды құрастырғандай әдісті шақырыңыз: findById(Integer id ) - id арқылы an objectіні табады; countFruitEntityByFruitName(String name) - белгілі бір аты бар жемістер санын санайды; Бұл әдіс атымен жасалған сұраулар; олар туралы оқып шығыңыз және FruitService сыныбында (Integer from, Integer to) арасындағы әдісті енгізіп, тізімге енгізілген провайдер_codeы өрісінің мәндері бойынша List<FruitEntity> іздеуді орындаңыз. белгілі бір интервалды таңдап, жұмыс нәтижесін консольде көрсетіңіз. Мысалы: жеткізуші нөмірі 5-тен 7-ге дейінгі барлық жемістерді табыңыз. Әдісті жүзеге асырмайынша, әрі қарай оқуға асықпаңыз, бұл көп уақытты алмайды. Әдіс атауы бойынша сұраулар туралы мақалада оқыған боларсыз: «Сіз бұл сияқты барлық сұрауларды жаза алмайсыз, бірақ қарапайымдарды жазуға болады». Неғұрлым күрделі сұраулар үшін @Query annotationсы пайдаланылады және SQL орнына JPQL пайдаланылады (осы мақаланы да ескеріңіз). Біздің жоба үшін JOIN сұрауларын келесідей жасай аласыз: Көктем қорқынышты емес немесе дерекқорға сұрақ қою - 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();

}
Стандартты SQL сұрауы келесідей болады: "fruit_table.fruit_name, provider_table.provider_name таңдаңыз fruit_table солға join provider_table on fruit_table.provider_code = provider_table.id". Мұнда корреспонденцияны оңай орнатуға болады: f ruit_tableFruitEntiy 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);
        }
Біз жобаны іске қосамыз және консольде жаңа журналдарды көреміз: жемістер кестесі және олардың жеткізушілері Жемістер1, null Жемістер2, Провайдер5 Жемістер3, Провайдер2 Жемістер4, Провайдер5 Жемістер5, null Жеміс6, null Жеміс7, null Жеміс8, null Жемістер9, null Жемістер кестесі жеткізушілер FruitEntity(id= 2, fruitName=Fruit2, providerCode=5) FruitEntity(id=3, fruitName=Fruit3, providerCode=2) FruitEntity(id=4, fruitName=Fruit4, providerCode=5) Жемістер және олардың жеткізушілері Fruit2 кестесі ,Provider5 Fruit3,Provider2 Fruit4 ,Provider5 Иә, егер сіз «жалған» және консольдегі жай SQL сұрауларынан шаршаған болсаңыз, yaml файлындағы орнына false мәнін қайтара аласыз. Неліктен бірінші кестеде нөл бар, сіз JOIN SQL туралы оқысаңыз, білесіз . Сонымен, біз дерекқорға сұраныстарды аяқтадық, сізде әлі де көптеген сұрақтар бар екеніне сенімдімін, бірақ сіз оларға жауап іздейсіз деп үміттенемін, мен іздеу жолдарын бөлектеуге тырыстым. Осы уақыт ішінде үйренгеніміздің барлығын қорытындылауға тырысайық: 1. Көктемде веб-serverді іске қосуға болады және бұл қиын емес. 2. Мұның бәрі қалай жұмыс істейтінін түсіну үшін теорияға сүңгу керек. Кітап туралы Көктем туралы мақала Пайдалы нәрселер туралы мақала 3. Түсінудің физикалық codeқа айналуы үшін codeтау керек және әрі қарай қозғалмас бұрын серіппелі жүктегіште қарапайым жобаларға қол жеткізіңіз. Жазылған codeты көшірмей, қайта жазған дұрыс. Мен сіз бен біз жұмыс істеп жатқан жобаны осында орналастырамын, бірақ мен сіздің хабардарлығыңызға сүйенемін және сіз ойланбастан көшіріп-қоймайтыныңызға сенімдімін. Git clone репозиторийіне сілтеме https://FromJava@bitbucket.org/FromJava/jd.git Бұл сілтемені қалай пайдалану керектігін білмейтіндер үшін екі оқу жобасын жүзеге асыруды ұсынамын: Көліктерді бояу жобасы: Бірінші класс: CarEntity{ Integer идентификатор; String modelName; Жол түсі; } Екінші класс: ColorEntity{ Integer идентификаторы; Жол түсі; бүтін баға; } Мәліметтер қорын толтырыңыз (түсіну оңай болуы үшін нақты атауларды ойлап табыңыз), орындаңыз: , нысан, репозиторийлер, қызметтер, стандартты және кестеаралық сұрауларды жасаңыз (BMW қызыл бояу қанша тұрады? Түсі қандай? ең қымбаты?Үлгілерді консольге алфавиттік ретпен жазу және т.б.); Кітапхана жобасы: Бірінші класс: BookEntity{ Integer id; String nameBook; бүтін yearCreat; бүтін автор идентификаторы; } Екінші класс: AutorEntity{ Integer id; Жолдың firstNameAutor; Жолдың lastNameAutor; } Мәліметтер қорын толтырыңыз (түсіну оңай болуы үшін нақты атауларды ойлап табыңыз), іске асырыңыз: нысан, репозиторийлер, қызметтер, стандартты және кесте аралық сұраныстарды жасаңыз (Кім қай кітапты жазды? Қай кітап бірінші жазылған? Қандай кітаптар жазылған? 1800 жылдан 1900 жылға дейін?Authorлардың қайсысы ең көп кітап жазды?); «Кітапхана» жобасының деректер қорын толтыру мысалдары Кітап кестесі BookEntity(id=1, nameBook=Виттен қайғы, yearCreat=1824, авторИд=1) BookEntity(id=2, nameBook=Соғыс және Бейбітшілік, yearCreat=1863, авторИд=2) BookEntity(id=3, nameBook=) Mtsyri, yearCreat=1838, авторИд=3) BookEntity(id=4, nameBook=Евгений Онегин, yearCreat=1833, авторИд=4) Authorлық кесте AuthorEntity(id=1, firstNameAuthor=Alexander, lastNameAuthor=Griboyedov) Aut=2 , firstNameAuthor=Lev, lastNameAuthor=Толстой) AuthorEntity(id=3, firstNameAuthor=Михаил, lastNameAuthor=Лермонтов) AuthorEntity(id=4, firstNameAuthor=Александр, lastNameAuthor=Пушкин) Барлығына сәттілік !
Пікірлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION