JavaRush /Java Blog /Random-JA /パート 3. データベースのスケルトン、java.sql の例を使用した最初の SQL コマンドを作成します。
Marat Sadykov
レベル 41

パート 3. データベースのスケルトン、java.sql の例を使用した最初の SQL コマンドを作成します。

Random-JA グループに公開済み
前編 後編
パート 3. データベースのスケルトン、java.sql の例を使用した最初の SQL コマンドを作成します。 - 1

Javaアプリケーション

3層組織

Java アプリケーションに戻りましょう。前の部分のバージョンは、初期アクションの正確さを制御するためにHelloWorldスタイルで作成されました。私たちは 3 層 (3 層) アーキテクチャを実装しています。英語の文献では、これは3tier/3layerと呼ばれることがよくあります。その簡単な本質は次のとおりです。
  • すべてのエンティティはモデルとして設計されています。これらは以下を含むオブジェクトです。
    • 属性のセット (クラスのプライベート フィールド)。
    • コンストラクター。
    • 属性を設定/読み取りするためのセッターとゲッター。
    • 上記以外のコードが含まれていないことが重要です。このようなオブジェクトは、 POJO (Plain Old Java Object)と呼ばれることがよくあります。
  • モデルを操作するためのすべてのロジックはサービス層によって実装されます。モデルのビジネス ルールを生成します。たとえば、Java アプリケーションからのリクエストを処理します。クエリ引数と返される結果には、多くの場合、モデル (またはそのコレクション) が含まれます。
  • リポジトリ層は DBMS とサービスの間の「仲介者」であり、データベースと直接連携して動作し、データベースとの対話を担当します。
パート 3. データベースのスケルトン、java.sql の例を使用した最初の SQL コマンドを作成します。 - 2 なぜこのような複合企業を形成する必要があるのでしょうか? 実際のところ、各層は他の層から最大限に分離されています。データベースの代わりにテキスト ファイルのセットがある場合は、コードの残りの部分には触れずに、リポジトリの実装を変更するだけで済みます。同様に、最小限の変更で別のサービスに接続/追加できます。大規模なシステムの場合、さまざまな層の実装をさまざまな人々に提供したり、さまざまな層の最適な実装を組み合わせて実験したりできます。アプリケーションのパッケージ、モデルリポジトリサービスを作成しましょう。対応するクラスが配置される場所になります。次のパートではサービス層に戻りますが、ここではモデルとリポジトリに注目します。 パート 3. データベースのスケルトン、java.sql の例を使用した最初の SQL コマンドを作成します。 - 3

モデル

すべてのエンティティ (株式、トレーダー、レート、トレーダーのアクション) とそれらに相当するテーブルには、人工主キーという共通の機能があります。したがって、基本クラスを作成しましょうBaseModel。すべてのモデルはそれを継承します。
package sql.demo.model;

import java.util.Objects;

// Базовый класс модели, имеющий ключ id
public class BaseModel {
    protected long id;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public BaseModel() {}

    public BaseModel(long id) {
        this.id = id;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        BaseModel baseModel = (BaseModel) o;
        return id == baseModel.id;
    }

    @Override
    public int hashCode() {
        return Objects.hash(id);
    }
}
以下はストックモデルの例です。記事の最後にある github リポジトリへのリンクをたどると、残りのモデルのリストを確認できます。
package sql.demo.model;

import java.math.BigDecimal;

// Модель акции
public class Share extends BaseModel{
    // поля SQL таблицы и соответствующие им поля модели
    // типы данных SQL
    private String name;    // Наименование
    private BigDecimal startPrice; // Начальная цена
    private int changeProbability; // Вероятность смены курса (в процентах)
    private int delta;   // Максимальное колебание (в процентах)стоимости акции в результате торгов


    public Share() {
    }

    public Share(long id, String name, BigDecimal startPrice, int changeProbability, int delta) {
        super(id);
        this.name = name;
        this.startPrice = startPrice;
        this.changeProbability = changeProbability;
        this.delta = delta;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    ... оставшиеся сеттеры/геттеры
}

JDBC

最初の部分では、データベースへの接続を確立して閉じる方法を学びました。さあ、次に進みましょう。JDBC を使用する段階を次の図に示します。 パート 3. データベースのスケルトン、java.sql の例を使用した最初の SQL コマンドを作成します。 - 4
  • Class.forName()クラスをロードし、DriverManager に登録します。
  • DriverManager.getConnection()返されますConnection– メソッドの引数で指定され、対応する JDBC ドライバー ( を使用してロードされたClass.forName()) を使用したデータベースへの接続が返されます。
  • createStatement()Statementデータベースへのクエリを作成できるオブジェクトを返します。もあります:
      CallableStatementDBMS 独自の SQL 関数とプロシージャ (ストアドと呼ばれます) を呼び出します。
    • PreparedStatementパラメータ化されたクエリやバッチ クエリの作成が容易になります。
  • 「手元に」あると、SQL クエリ言語コマンドの形式でリクエストを DBMS 実行に直接送信し、 の形式で応答を返すことができstatementます。便宜上、次のものがあります。 execute()ResultSet
    • executeQuery()– DBMS からデータを読み取るため。
    • executeUpdate()– DBMS 内のデータを変更する。
  • サーバー応答自体は、 、などを反復処理することで、のResultSet形式で処理できます。getter: , ...を通じて個々の結果フィールドを取得できます。first()last()next()getInteger()getString()
ResultSetDBMS を使用した後、リソースを節約するために、後ろのオブジェクトを (正しい順序で!) 閉じStatementConnectionリソースを節約すること をお勧めします。図上のシーケンスの上位にあるオブジェクトを閉じるときは、そのオブジェクトを操作する過程で生成されたすべてのオブジェクトをカスケードして閉じることになることに注意してください。したがって、接続を閉じると、接続すべてが閉じられStatement、彼らの助けで受け取ったすべてが閉じられますResultSet

リポジトリの実装

JDBC の理論的な部分を終えたら、リポジトリの実装に進みましょう。アーキテクチャ的には次のように実装します。
  • DBMS の操作の最も一般的な部分を共通の先祖に移動しますBaseTable
  • 実行する論理演算はインターフェイスで宣言されますTableOperation
パート 3. データベースのスケルトン、java.sql の例を使用した最初の SQL コマンドを作成します。 - 5 新しいリポジトリはクラスを継承しBaseTable、インターフェイスを実装しますTableOperation。したがって、インターフェースで宣言されたメソッドの実装を記述する必要がありますTableOperation。この場合、親クラスのメソッドを使用できますBaseTable。現時点では、インターフェイスはテーブルを作成するためのメソッドを宣言しています。
package sql.demo.repository;
import java.sql.SQLException;

// Операции с tableми
public interface TableOperations {
    void createTable() throws SQLException; // создание таблицы
    void createForeignKeys() throws SQLException; // создание связей между tableми
    void createExtraConstraints() throws SQLException; // создание дополнительных правил для значений полей таблиц
}
この資料を学習すると、メソッド宣言のリストが拡張されます ( read(), update()….)。新しい機能は次の 2 つのステップで実装します。
  1. 新しいインターフェイス メソッドの形式でテーブルを操作する別の機能を追加しましょう。
  2. 次に、インターフェイスを実装するクラスで、インターフェイスによって生成された新しいメソッドでのソフトウェア実装を説明します。
(株式)のリポジトリの例Share。主なロジックは、テーブルを作成し、フィールドに SQL データ型を指定し、制限を追加するためのコマンドにあります。
package sql.demo.repository;
import java.sql.SQLException;

public class Shares extends BaseTable implements TableOperations{

    public Shares() throws SQLException {
        super("shares");
    }

    @Override
    public void createTable() throws SQLException {
        super.executeSqlStatement("CREATE TABLE shares(" +
                "id BIGINT AUTO_INCREMENT PRIMARY KEY," +
                "name VARCHAR(255) NOT NULL," +
                "startPrice DECIMAL(15,2) NOT NULL DEFAULT 10," +
                "changeProbability INTEGER NOT NULL DEFAULT 25,"+
                "delta INTEGER NOT NULL DEFAULT 15)", "Создана table " + tableName);
    }

    @Override
    public void createForeignKeys() throws SQLException {
    }

    @Override
    public void createExtraConstraints() throws SQLException {
        super.executeSqlStatement(
                " ALTER TABLE shares ADD CONSTRAINT check_shares_delta CHECK(delta <= 100 and delta > 0)",
                "Cоздано ограничение для shares, поле delta = [1,100]");
        super.executeSqlStatement(
                " ALTER TABLE shares ADD CONSTRAINT check_shares_changeProbability " +
                        "CHECK(changeProbability <= 100 and changeProbability > 0)",
                "Cоздано ограничение для shares, поле changeProbability = 1..100");

    }
}
他のリポジトリと親クラスのリストは、記事の最後にある github リポジトリへのリンクから入手できます。もちろん、別のプログラム設計を行ったり、共通部分を親クラスに移動したり、共通メソッドを強調表示したりするなど、プログラムのより徹底的なリファクタリングを行うこともできます。ただし、一連の記事の主な目的はデータベースを直接操作することなので、必要に応じてプログラムなどを設計することも、自分で行うこともできます。現在のプロジェクト構造: パート 3. データベースのスケルトン、java.sql の例を使用した最初の SQL コマンドを作成します。 - 6 リポジトリとモデルに加えて、StockExchangeDBエミュレーションの一般的な管理のためのクラスを追加で作成しました。この段階では、リポジトリを管理します (次のパートではサービスに進みます)。それらを宣言し、テーブルの作成を開始します。
package sql.demo;
import org.h2.tools.DeleteDbFiles;
import sql.demo.repository.*;
import java.sql.*;

public class StockExchangeDB {
    // Блок объявления констант
    public static final String DB_DIR = "c:/JavaPrj/SQLDemo/db";
    public static final String DB_FILE = "stockExchange";
    public static final String DB_URL = "jdbc:h2:/" + DB_DIR + "/" + DB_FILE;
    public static final String DB_Driver = "org.h2.Driver";

    // Таблицы СУБД
    Traiders traiders;
    ShareRates shareRates;
    Shares shares;
    TraiderShareActions traiderShareActions;

    // Получить новое соединение с БД
    public static Connection getConnection() throws SQLException {
        return DriverManager.getConnection(DB_URL);
    }

    // Инициализация
    public StockExchangeDB(boolean renew) throws SQLException, ClassNotFoundException {
        if (renew)
            DeleteDbFiles.execute(DB_DIR, DB_FILE, false);
        Class.forName(DB_Driver);
        // Инициализируем таблицы
        traiders = new Traiders();
        shares = new Shares();
        shareRates = new ShareRates();
        traiderShareActions = new TraiderShareActions();
    }

    // Инициализация по умолчанию, без удаления file БД
    public StockExchangeDB() throws SQLException, ClassNotFoundException {
        this(false);
    }

    // Creation всех таблиц и внешних ключей
    public void createTablesAndForeignKeys() throws SQLException {
        shares.createTable();
        shareRates.createTable();
        traiders.createTable();
        traiderShareActions.createTable();
        // Creation ограничений на поля таблиц
        traiderShareActions.createExtraConstraints();
        shares.createExtraConstraints();
        // Creation внешних ключей (связи между tableми)
        shareRates.createForeignKeys();
        traiderShareActions.createForeignKeys();
    }


    public static void main(String[] args) {
        try{
            StockExchangeDB stockExchangeDB = new StockExchangeDB(true);
            stockExchangeDB.createTablesAndForeignKeys();
        } catch (SQLException e) {
            e.printStackTrace();
            System.out.println("Ошибка SQL !");
        } catch (ClassNotFoundException e) {
            System.out.println("JDBC драйвер для СУБД не найден!");
        }
    }
}
実行結果: パート 3. データベースのスケルトン、java.sql の例を使用した最初の SQL コマンドを作成します。 - 7

まとめ

記事の 2 番目と 3 番目の部分では、次のことを学びました。
  • SQL データ型。
  • データベーステーブル。
  • データベースの設計: テーブル構造とそれらの間の関係。
  • データベース テーブルの作成、フィールドおよびテーブル間の関係に対する制限の設定に関する SQL クエリ言語。
  • JDBC との対話の詳細。
  • データ処理アプリケーションの 3 層 (3 層) モデル/リポジトリ/サービス アーキテクチャ。

役立つリンク

コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION