前編 後編
Javaアプリケーション
3層組織
Java アプリケーションに戻りましょう。前の部分のバージョンは、初期アクションの正確さを制御するためにHelloWorldスタイルで作成されました。私たちは 3 層 (3 層) アーキテクチャを実装しています。英語の文献では、これは3tier/3layerと呼ばれることがよくあります。その簡単な本質は次のとおりです。- すべてのエンティティはモデルとして設計されています。これらは以下を含むオブジェクトです。
- 属性のセット (クラスのプライベート フィールド)。
- コンストラクター。
- 属性を設定/読み取りするためのセッターとゲッター。
- 上記以外のコードが含まれていないことが重要です。このようなオブジェクトは、 POJO (Plain Old Java Object)と呼ばれることがよくあります。
- モデルを操作するためのすべてのロジックはサービス層によって実装されます。モデルのビジネス ルールを生成します。たとえば、Java アプリケーションからのリクエストを処理します。クエリ引数と返される結果には、多くの場合、モデル (またはそのコレクション) が含まれます。
- リポジトリ層は DBMS とサービスの間の「仲介者」であり、データベースと直接連携して動作し、データベースとの対話を担当します。
モデル
すべてのエンティティ (株式、トレーダー、レート、トレーダーのアクション) とそれらに相当するテーブルには、人工主キーという共通の機能があります。したがって、基本クラスを作成しましょう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 を使用する段階を次の図に示します。Class.forName()
クラスをロードし、DriverManager に登録します。DriverManager.getConnection()
返されますConnection
– メソッドの引数で指定され、対応する JDBC ドライバー ( を使用してロードされたClass.forName()
) を使用したデータベースへの接続が返されます。createStatement()
Statement
データベースへのクエリを作成できるオブジェクトを返します。もあります:PreparedStatement
パラメータ化されたクエリやバッチ クエリの作成が容易になります。
CallableStatement
DBMS 独自の SQL 関数とプロシージャ (ストアドと呼ばれます) を呼び出します。- 「手元に」あると、SQL クエリ言語コマンドの形式でリクエストを DBMS 実行に直接送信し、 の形式で応答を返すことができ
statement
ます。便宜上、次のものがあります。execute()
ResultSet
executeQuery()
– DBMS からデータを読み取るため。
executeUpdate()
– DBMS 内のデータを変更する。 - サーバー応答自体は、 、などを反復処理することで、の
ResultSet
形式で処理できます。getter: , ...を通じて個々の結果フィールドを取得できます。first()
last()
next()
getInteger()
getString()
ResultSet
DBMS を使用した後、リソースを節約するために、後ろのオブジェクトを (正しい順序で!) 閉じStatement
てConnection
リソースを節約すること をお勧めします。図上のシーケンスの上位にあるオブジェクトを閉じるときは、そのオブジェクトを操作する過程で生成されたすべてのオブジェクトをカスケードして閉じることになることに注意してください。したがって、接続を閉じると、接続すべてが閉じられStatement
、彼らの助けで受け取ったすべてが閉じられますResultSet
。
リポジトリの実装
JDBC の理論的な部分を終えたら、リポジトリの実装に進みましょう。アーキテクチャ的には次のように実装します。- DBMS の操作の最も一般的な部分を共通の先祖に移動します
BaseTable
。 - 実行する論理演算はインターフェイスで宣言されます
TableOperation
。
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 つのステップで実装します。
- 新しいインターフェイス メソッドの形式でテーブルを操作する別の機能を追加しましょう。
- 次に、インターフェイスを実装するクラスで、インターフェイスによって生成された新しいメソッドでのソフトウェア実装を説明します。
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 リポジトリへのリンクから入手できます。もちろん、別のプログラム設計を行ったり、共通部分を親クラスに移動したり、共通メソッドを強調表示したりするなど、プログラムのより徹底的なリファクタリングを行うこともできます。ただし、一連の記事の主な目的はデータベースを直接操作することなので、必要に応じてプログラムなどを設計することも、自分で行うこともできます。現在のプロジェクト構造: リポジトリとモデルに加えて、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 драйвер для СУБД не найден!");
}
}
}
実行結果:
まとめ
記事の 2 番目と 3 番目の部分では、次のことを学びました。- SQL データ型。
- データベーステーブル。
- データベースの設計: テーブル構造とそれらの間の関係。
- データベース テーブルの作成、フィールドおよびテーブル間の関係に対する制限の設定に関する SQL クエリ言語。
- JDBC との対話の詳細。
- データ処理アプリケーションの 3 層 (3 層) モデル/リポジトリ/サービス アーキテクチャ。
役立つリンク
- H2 データベース エンジン (英語) ;
- SQL コマンドの説明 (英語) ;
- H2 (英語) のデータ型。
- SQL 予約語のリスト。
- Martin Graber 著『Understanding SQL』という書籍。
- BigDecimal の操作の基本。
- GitHub リポジトリ
GO TO FULL VERSION