JavaRush /Java Blog /Random-TW /第 3 部分:我們使用 java.sql 範例建立資料庫的骨架,第一個 SQL 指令。
Marat Sadykov
等級 41

第 3 部分:我們使用 java.sql 範例建立資料庫的骨架,第一個 SQL 指令。

在 Random-TW 群組發布
第一部分 第二部分
第 3 部分:我們使用 java.sql 範例建立資料庫的骨架,第一個 SQL 指令。 - 1

Java應用程式

三層組織

讓我們回到 Java 應用程式。上一部分的版本是以HelloWorld風格建立的,以控制初始操作的正確性。我們實作了三層(三層)架構,在英文文獻中通常稱為3tier/3layer。其簡要實質如下:
  • 所有實體都被設計為模型。這些物件包含:
    • 一組屬性(類別的私有欄位)。
    • 構造函數。
    • 用於設定/讀取屬性的 Setter 和 getter。
    • 重要的是它們不包含上述程式碼之外的任何其他程式碼。此類物件通常稱為POJO(普通舊 Java 物件)。
  • 使用模型的所有邏輯均由服務層實現。它為模型產生業務規則。例如,處理來自 Java 應用程式的請求。查詢參數和傳回的結果通常包括模型(或其集合)。
  • Repository層是DBMS和Service之間的“中介”,直接與資料庫合作並負責與其互動。
第 3 部分:我們使用 java.sql 範例建立資料庫的骨架,第一個 SQL 指令。 - 2 為什麼我們需要組成這樣一個企業集團?事實上,每一層都最大限度地與其他層隔離。如果我們有一組文字檔案而不是資料庫,那麼我們只需要更改儲存庫的實現,而無需觸及其餘程式碼。同樣,我們可以透過最小的更改連接/添加另一個服務。對於大型系統,我們可以將不同層的實現交給不同的人,或透過組合不同層的最佳實現來進行實驗。讓我們為我們的應用程式建立套件modelrepositoryservice,對應的類別將位於其中。我們將在下面的部分中回到服務層,但現在我們將專注於模型和儲存庫。 第 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 的各個階段如下圖所示: 第 3 部分:我們使用 java.sql 範例建立資料庫的骨架,第一個 SQL 指令。 - 4
  • Class.forName()載入該類別並將其註冊到DriverManager;
  • DriverManager.getConnection()將傳回Connection– 與方法參數中指定的資料庫的連接,並使用對應的 JDBC 驅動程式(使用 載入Class.forName())。
  • createStatement()將返回給我們Statement一個對象,我們可以根據該對象對資料庫進行查詢。還有:
      CallableStatement呼叫 DBMS 自己的 SQL 函數和過程(它們稱為儲存)。
    • PreparedStatement促進參數化和批量查詢的創建。
  • 擁有「手中」statementexecute()允許您以 SQL 查詢語言命令的形式直接向 DBMS 執行發送請求,並以ResultSet. 為了方便起見,有:
    • executeQuery()– 用於從 DBMS 讀取資料。
    • executeUpdate()– 修改 DBMS 中的資料。
  • 伺服器回應本身ResultSet可以透過迭代first()last()next()等形式進行處理。我們可以透過 getter 取得各個結果欄位:getInteger(), getString()...
應該記住,在使用 DBMS 後,為了節省資源,建議關閉後面的物件(按正確的順序!)ResultSetStatementConnection節省資源。請記住,當關閉圖中順序較高的物件時,您將級聯關閉在使用該物件的過程中產生的所有物件。因此,關閉連接將導致所有連接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()…)。我們將分兩步驟實現新功能:
  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

概括

在文章的 第二部分和第三部分我們了解到:
  • SQL 資料型別。
  • 資料庫表。
  • 設計資料庫:表結構及其之間的關係。
  • SQL查詢語言用於建立資料庫表格、設定欄位限制以及表格之間的關係。
  • 有關與 JDBC 互動的更多資訊。
  • 資料處理應用程式的三層(三層)模型/儲存庫/服務架構。

有用的連結

留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION