JavaRush /Java 博客 /Random-ZH /第 3 部分:我们使用 java.sql 示例创建数据库的骨架,第一个 SQL 命令。
Marat Sadykov
第 41 级

第 3 部分:我们使用 java.sql 示例创建数据库的骨架,第一个 SQL 命令。

已在 Random-ZH 群组中发布
第一部分 第二部分
第 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