JavaRush /Blog Java /Random-VI /Phần 3. Chúng ta tạo khung cơ sở dữ liệu, các lệnh SQL đầ...
Marat Sadykov
Mức độ

Phần 3. Chúng ta tạo khung cơ sở dữ liệu, các lệnh SQL đầu tiên bằng cách sử dụng các ví dụ java.sql.

Xuất bản trong nhóm
Phần thứ nhất Phần thứ hai
Phần 3. Chúng ta tạo khung cơ sở dữ liệu, các lệnh SQL đầu tiên bằng cách sử dụng các ví dụ java.sql.  - 1

ứng dụng Java

tổ chức 3 cấp

Hãy quay lại ứng dụng Java. Phiên bản từ phần trước được tạo theo phong cách HelloWorld để kiểm soát tính chính xác của các hành động ban đầu. Chúng tôi triển khai kiến ​​trúc ba tầng (ba lớp), mà trong tài liệu tiếng Anh thường được gọi là 3tier/3layer . Bản chất ngắn gọn của nó là như sau:
  • Tất cả các thực thể được thiết kế dưới dạng mô hình. Đây là những đối tượng có chứa:
    • Một tập hợp các thuộc tính (các trường riêng của lớp).
    • (Các) nhà xây dựng.
    • Setters và getters để cài đặt/đọc thuộc tính.
    • Điều quan trọng là chúng không chứa bất kỳ mã nào khác ngoài mã trên. Các đối tượng như vậy thường được gọi là POJO (Đối tượng Java thuần túy cũ).
  • Tất cả logic để làm việc với các mô hình đều được triển khai bởi lớp Dịch vụ. Nó tạo ra các quy tắc kinh doanh cho các mô hình. Ví dụ: xử lý các yêu cầu từ một ứng dụng Java. Các đối số truy vấn và kết quả trả về thường bao gồm các mô hình (hoặc tập hợp các mô hình đó).
  • Lớp Kho lưu trữ là một “trung gian” giữa DBMS và Dịch vụ, làm việc trực tiếp với cơ sở dữ liệu và chịu trách nhiệm tương tác với nó.
Phần 3. Chúng ta tạo khung cơ sở dữ liệu, các lệnh SQL đầu tiên bằng cách sử dụng các ví dụ java.sql.  - 2 Tại sao chúng ta lại cần phải thành lập một tập đoàn như vậy? Thực tế là mỗi lớp được cách ly tối đa với các lớp khác. Nếu thay vì cơ sở dữ liệu, chúng ta có một tập hợp các tệp văn bản thì chúng ta chỉ cần thay đổi cách triển khai Kho lưu trữ mà không cần chạm vào phần còn lại của mã. Tương tự, chúng ta có thể kết nối/thêm Dịch vụ khác với những thay đổi tối thiểu. Đối với các hệ thống lớn, chúng tôi có thể cung cấp việc triển khai các lớp khác nhau cho những người khác nhau hoặc thử nghiệm bằng cách kết hợp việc triển khai tối ưu các lớp khác nhau. Hãy tạo các gói model , kho lưu trữ , dịch vụ cho ứng dụng của chúng ta, nơi đặt các lớp tương ứng. Chúng ta sẽ quay lại lớp Dịch vụ trong các phần sau, nhưng bây giờ chúng ta sẽ chú ý đến các mô hình và kho lưu trữ. Phần 3. Chúng ta tạo khung cơ sở dữ liệu, các lệnh SQL đầu tiên bằng cách sử dụng các ví dụ java.sql.  - 3

Người mẫu

Tất cả các thực thể của chúng tôi (cổ phiếu, nhà giao dịch, tỷ giá và hành động của nhà giao dịch) và các đối tượng tương đương trong bảng của chúng đều có một đặc điểm chung - khóa chính nhân tạo. Vì vậy, hãy tạo một lớp cơ sở BaseModel. Tất cả các mô hình sẽ kế thừa từ nó.
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);
    }
}
Dưới đây là một ví dụ về mô hình chứng khoán. Bạn có thể xem phần còn lại của danh sách mô hình bằng cách nhấp vào liên kết đến kho github ở cuối bài viết.
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

Trong phần đầu tiên, chúng ta đã học cách thiết lập kết nối tới cơ sở dữ liệu và đóng nó. Bây giờ chúng ta hãy tiếp tục. Các giai đoạn làm việc với JDBC được thể hiện trong sơ đồ sau: Phần 3. Chúng ta tạo khung cơ sở dữ liệu, các lệnh SQL đầu tiên bằng cách sử dụng các ví dụ java.sql.  - 4
  • Class.forName()tải lớp và đăng ký nó với DriverManager;
  • DriverManager.getConnection()sẽ trả về Connection– một kết nối tới cơ sở dữ liệu được chỉ định trong đối số phương thức và sử dụng trình điều khiển JDBC tương ứng (được tải bằng Class.forName()).
  • createStatement()sẽ trả về cho chúng ta Statementmột đối tượng trên cơ sở đó chúng ta có thể tạo các truy vấn tới cơ sở dữ liệu. Cũng có:
      CallableStatementđể gọi các hàm và thủ tục SQL của chính DBMS (chúng được gọi là được lưu trữ).
    • PreparedStatementtạo điều kiện thuận lợi cho việc tạo ra các truy vấn được tham số hóa và theo lô.
  • Có “trong tay” statementsẽ execute()cho phép bạn gửi yêu cầu dưới dạng lệnh ngôn ngữ truy vấn SQL trực tiếp đến quá trình thực thi DBMS và trả về phản hồi dưới dạng ResultSet. Để thuận tiện có:
    • executeQuery()– để đọc dữ liệu từ DBMS.
    • executeUpdate()– để sửa đổi dữ liệu trong DBMS.
  • Bản thân phản hồi của máy chủ ResultSetcó thể được xử lý dưới dạng bằng cách lặp qua first(), last(), next()v.v. Chúng tôi có thể nhận các trường kết quả riêng lẻ thông qua getters: getInteger(), getString()...
Cần lưu ý rằng sau khi làm việc với DBMS, để tiết kiệm tài nguyên, bạn nên đóng các đối tượng phía sau (theo đúng thứ tự!) ResultSetvà tiết kiệm tài nguyên Statement. ConnectionHãy nhớ rằng, khi đóng một đối tượng có thứ tự cao hơn trên sơ đồ, bạn sẽ đóng theo tầng tất cả các đối tượng được tạo trong quá trình làm việc với nó. Do đó, việc đóng một kết nối sẽ dẫn đến việc đóng tất cả kết nối đó Statementvà tất cả ResultSetnhững gì nhận được với sự trợ giúp của họ.

Triển khai kho lưu trữ

Sau phần JDBC lý thuyết, chúng ta hãy chuyển sang phần triển khai kho lưu trữ. Chúng tôi triển khai nó theo kiến ​​trúc như sau:
  • Chúng ta sẽ chuyển những phần chung nhất khi làm việc với DBMS vào một tổ tiên chung - BaseTable;
  • Các thao tác logic mà chúng ta sẽ thực hiện sẽ được khai báo trong giao diện TableOperation;
Phần 3. Chúng ta tạo khung cơ sở dữ liệu, các lệnh SQL đầu tiên bằng cách sử dụng các ví dụ java.sql.  - 5 Kho lưu trữ mới sẽ kế thừa từ lớp BaseTablevà triển khai giao diện TableOperation. Vì vậy, chúng ta cần viết phần thực thi của các phương thức được khai báo trong giao diện TableOperation. Trong trường hợp này, chúng ta có thể sử dụng các phương thức của lớp cha BaseTable. Lúc này giao diện khai báo các phương thức tạo bảng:
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; // создание дополнительных правил для значений полей таблиц
}
Khi bạn nghiên cứu tài liệu, danh sách khai báo phương thức sẽ mở rộng ( read(), update()….). Chúng tôi sẽ triển khai các tính năng mới theo hai bước:
  1. Hãy thêm một khả năng khác để làm việc với bảng dưới dạng phương thức giao diện mới.
  2. Tiếp theo, trong các lớp triển khai giao diện, chúng ta sẽ mô tả cách triển khai phần mềm theo các phương thức mới do giao diện tạo ra.
Kho lưu trữ ví dụ cho Share(cổ phiếu). Logic chính nằm ở các lệnh tạo bảng, chỉ định kiểu dữ liệu SQL cho các trường và thêm các hạn chế:
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");

    }
}
Danh sách các kho lưu trữ khác và lớp cha có sẵn thông qua liên kết đến kho lưu trữ github ở cuối bài viết. Tất nhiên, bạn có thể thực hiện một thiết kế chương trình khác hoặc tái cấu trúc chương trình kỹ lưỡng hơn: di chuyển các phần chung vào lớp cha, làm nổi bật các phương thức chung, v.v. Nhưng mục tiêu chính của loạt bài là làm việc trực tiếp với cơ sở dữ liệu nên nếu muốn, bạn có thể thiết kế chương trình và những thứ tương tự, bạn có thể tự làm. Cấu trúc dự án hiện tại: Phần 3. Chúng ta tạo khung cơ sở dữ liệu, các lệnh SQL đầu tiên bằng cách sử dụng các ví dụ java.sql.  - 6 Ngoài các kho lưu trữ và mô hình, chúng tôi còn tạo thêm một lớp StockExchangeDBđể quản lý chung quá trình mô phỏng của mình. Ở giai đoạn này, chúng tôi quản lý kho lưu trữ (trong phần tiếp theo chúng tôi sẽ chuyển sang dịch vụ). Chúng tôi khai báo chúng và bắt đầu tạo bảng:
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 драйвер для СУБД не найден!");
        }
    }
}
Kết quả thực hiện: Phần 3. Chúng ta tạo khung cơ sở dữ liệu, các lệnh SQL đầu tiên bằng cách sử dụng các ví dụ java.sql.  - 7

Bản tóm tắt

Trong phần thứ hai và thứ ba của bài viết, chúng ta đã học được:
  • Các kiểu dữ liệu SQL.
  • Các bảng cơ sở dữ liệu.
  • Thiết kế cơ sở dữ liệu: cấu trúc bảng và mối quan hệ giữa chúng.
  • Ngôn ngữ truy vấn SQL trong việc tạo bảng cơ sở dữ liệu, thiết lập các hạn chế trên các trường và mối quan hệ giữa các bảng.
  • Tìm hiểu thêm về tương tác với JDBC.
  • Kiến trúc Mô hình/Kho lưu trữ/Dịch vụ ba tầng (ba lớp) của một ứng dụng xử lý dữ liệu.

Liên kết hữu ích

Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION