JavaRush /Java Blog /Random-JA /春は怖くない、またはデータベースに質問する方法
Павел
レベル 11

春は怖くない、またはデータベースに質問する方法

Random-JA グループに公開済み
記事のサイクルの内容 今日、私たちはプロジェクトの一環としてデータベースの作業を最終仕上げしています。すべてを正しく行った場合は、次の依存関係を持つ pom が作成されるはずです。
<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: 行を見つけて (show 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 (?, ?, ?)
論理的に考えてみましょう。まず、冬眠という言葉があります。これは、この秘密主義者が毛皮で覆われた足をここに置いたことを意味します。インターネットで彼について読んだ後、私たちはHiber氏が ORM モデルの実装者であることを知りました。オブジェクト リレーショナル モデルは、ソフトウェア オブジェクトとデータベース内のレコードの間の関係を記述します。この考えを修正した後、引き続き論理的に考えます。一方にはFruitEntityオブジェクトがあり、これには 3 つのフィールドがあります。文字列フルーツ名; 整数のプロバイダーコード。 一方、データベースFruit_tableには、フィールドid_fruitタイプinteger、 fruit_name タイプvarchar(255)provider_codeタイプinteger を持つテーブルがあります。 大まかに言えば、Hibernate はFruitEntityオブジェクトを取得し、オブジェクトのフィールドの値を取り出して、対応するテーブルのフィールドに書き込みます。質問があります。InitiateUtilsクラスでフルーツ テーブルへの入力を実装しましたが、何らかの理由で値を 2 つのフィールドのみに設定しました。3 番目のフィールドはどこですか?
new FruitEntity()
        .setFruitName("Fruit1")//раз
        .setProviderCode(Math.abs(new Random().nextInt() % 10)),//два
                                            //три???
この問題については、前々回の記事で簡単に触れましたので、ご自身で理解していただければと思います。まず、ここにないフィールドを見つけてください。そうすればすべてがわかります。よくやった、Hiber は私たちのために大量のリクエストを生成してくれました。しかし、私たちは盲目的ではないので、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およびProviderEntityInitiateUtilsクラスで使用し、結果をコンソールに出力します。(ちなみに、知らなかった場合は、sout と入力して Enter キーを押すと、「System.out.println()」をすぐに書くことができます。同じことが「public static void main(String[] args)」でも機能します。{} 「 psvm と入力するだけで、そこに移動します」など)。すでに対処済みだと思いますので、次に進む準備ができています。FruitRepositoryインターフェイスに移動して、次のメソッドの入力を開始します (つまり、コピーではなく入力します): List<FruitEntity> f 次の結果が得られるはずです。 クエリを作成しているかのようにメソッドを呼び出すだけです: findById(Integer id) ) - ID によってオブジェクトを検索します。countFruitEntityByFruitName(String name) - 特定の名前を持つ果物の数を数えます。これらはメソッドの名前によって生成されるクエリです。 必ず説明を読み、FruitServiceクラスにメソッドbetween(Integer from, Integer to)を実装して、メソッドに含まれるProvider_codeフィールドの値によって List<FruitEntity> を検索します。一定間隔で作業を行い、作業結果をコンソールに表示します。例: サプライヤー番号が 5 から 7 までのすべての果物を検索します。メソッドを実装するまで、急いで読み進めないでください。それほど時間はかかりません。メソッド名によるクエリに関する記事で「このようにすべてのクエリを作成することはできませんが、単純なクエリは作成できます。」を読んだことがあるかもしれません。より複雑なクエリの場合は、@Query アノテーションが使用され、 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 クエリは次のようになります。 「select Fruit_table.fruit_name、provider_table.provider_name from Fruit_table left 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);
        }
プロジェクトを起動すると、コンソールに新しいログが表示されます。 フルーツとそのサプライヤーの表 Fruit1,null Fruit2,Provider5 Fruit3,Provider2 Fruit4,Provider5 Fruit5,null Fruit6,null Fruit7,null Fruit8,null Fruit9,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 を返すことができます。最初のテーブルに null がある理由は、 JOIN SQLを読めばわかります。これでデータベースへのクエリは完了です。まだ多くの質問があると思いますが、それらに対する答えを探していただければ幸いです。検索パスを強調表示してみました。この間に学んだことをすべて要約してみましょう。 1. Spring で Web サーバーを実行できますが、それは難しくありません。2. すべてがどのように機能するかを理解するには、理論を詳しく理解する必要があります。 本について Spring に関する記事 役立つ記事 3. 理解を物理的なコードに変えるには、コーディングする必要があります。先に進む前に、spring-boot で簡単なプロジェクトに手を付けてください。そして、書かれたコードをコピーするのではなく、書き直す方が良いでしょう。あなたと私が取り組んできたプロジェクトをここに掲載しますが、私はあなたの認識に依存しており、あなたがむやみにコピー&ペーストしないことを確信しています。 git clone リポジトリへのリンク https://FromJava@bitbucket.org/FromJava/jd.git このリンクの使用方法がわからない人のために、 2 つのトレーニング プロジェクトを実装することをお勧めします: 車の塗装に関するプロジェクト: 第一クラス: CarEntity{ Integer ID; 文字列モデル名; 文字列の色。2 番目のクラス: ColorEntity{ 整数 ID; 文字列の色。整数の価格。データベースにデータを入力し (理解しやすいように現実的な名前を考えてください)、エンティティ、リポジトリ、サービスを実装し、標準クエリとクロステーブル クエリを作成します (BMW を赤に塗装するにはいくらかかりますか?色は何ですか)最も高価ですか? アルファベット順などでモデルをコンソールに書き込みます); ライブラリ プロジェクト: 最初のクラス: BookEntity{ 整数 ID; 文字列 nameBook; 整数 yearCreate; 整数の autorId; 2 番目のクラス: AutorEntity{ 整数 ID; 文字列 firstNameAutor; 文字列 lastNameAutor; データベースにデータを入力し (理解しやすいように現実的な名前を考えます)、エンティティ、リポジトリ、サービスを実装し、標準クエリとテーブル間クエリを作成します (誰がどの本を書いたのか? どの本が最初に書かれたのか? どの本が書かれたのか) 1800 年から 1900 年まで?最も多くの本を書いた著者は誰ですか?); 「ライブラリ」プロジェクトデータベースへの入力例 書籍テーブル BookEntity(id=1, nameBook=Woe from Wit, yearCreat=1824, authorId=1) BookEntity(id=2, nameBook=戦争と平和, 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=Griboyedov) AuthorEntity(id=2) , firstNameAuthor=Lev, lastNameAuthor=Tolstoy) AuthorEntity(id=3, firstNameAuthor=Mikhail, lastNameAuthor=Lermontov) AuthorEntity(id=4, firstNameAuthor=Alexander, lastNameAuthor=Pushkin) 皆さん、またお会いしましょう!
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION