JavaRush /مدونة جافا /Random-AR /الجزء 3. نقوم بإنشاء الهيكل العظمي لقاعدة البيانات الخاصة...
Marat Sadykov
مستوى

الجزء 3. نقوم بإنشاء الهيكل العظمي لقاعدة البيانات الخاصة بنا، أوامر SQL الأولى باستخدام أمثلة java.sql.

نشرت في المجموعة
الجزء الأول الجزء الثاني
الجزء 3. نقوم بإنشاء الهيكل العظمي لقاعدة البيانات الخاصة بنا، أوامر SQL الأولى باستخدام أمثلة java.sql.  - 1

تطبيق جافا

منظمة من 3 طبقات

دعنا نعود إلى تطبيق جافا. تم إنشاء الإصدار من الجزء السابق بأسلوب HelloWorld للتحكم في صحة الإجراءات الأولية. نحن نطبق بنية ثلاثية الطبقات (ثلاثية الطبقات)، والتي يُطلق عليها غالبًا في الأدب الإنجليزي اسم 3tier/3layer . جوهرها الموجز هو كما يلي:
  • تم تصميم جميع الكيانات كنماذج. هذه هي الكائنات التي تحتوي على:
    • مجموعة من السمات (الحقول الخاصة بالفئة).
    • المنشئ (المنشئون).
    • أدوات الضبط والحروف لإعداد/قراءة السمات.
    • ومن المهم ألا تحتوي على أي كود آخر غير ما سبق. غالبًا ما تسمى هذه الكائنات POJO (كائن Java القديم العادي).
  • يتم تنفيذ كل منطق العمل مع النماذج بواسطة طبقة الخدمة. فهو يولد قواعد العمل للنماذج. على سبيل المثال، معالجة الطلبات من تطبيق Java. تتضمن وسائط الاستعلام والنتائج التي يتم إرجاعها غالبًا نماذج (أو مجموعات منها).
  • طبقة المستودع هي "وسيط" بين نظام إدارة قواعد البيانات والخدمة، وتعمل مباشرة مع قاعدة البيانات وتكون مسؤولة عن التفاعل معها.
الجزء 3. نقوم بإنشاء الهيكل العظمي لقاعدة البيانات الخاصة بنا، أوامر SQL الأولى باستخدام أمثلة java.sql.  - 2 لماذا نحتاج حتى إلى تشكيل مثل هذا التكتل؟ والحقيقة هي أن كل طبقة معزولة إلى أقصى حد عن الطبقات الأخرى. إذا كان لدينا مجموعة من الملفات النصية بدلاً من قاعدة البيانات، فسنحتاج فقط إلى تغيير تنفيذ المستودع دون لمس بقية التعليمات البرمجية. وبالمثل، يمكننا توصيل/إضافة خدمة أخرى مع الحد الأدنى من التغييرات. بالنسبة للأنظمة الكبيرة، يمكننا تنفيذ طبقات مختلفة لأشخاص مختلفين أو التجربة من خلال الجمع بين التطبيقات المثالية لطبقات مختلفة. لنقم بإنشاء حزم نموذجية ومستودعات وخدمة لتطبيقنا، حيث سيتم تحديد موقع الفئات المقابلة . سنعود إلى طبقة الخدمة في الأجزاء التالية، ولكن في الوقت الحالي سنهتم بالنماذج والمستودعات. الجزء 3. نقوم بإنشاء الهيكل العظمي لقاعدة البيانات الخاصة بنا، أوامر SQL الأولى باستخدام أمثلة java.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);
    }
}
فيما يلي مثال لنموذج المخزون. يمكنك الاطلاع على بقية قوائم النماذج باتباع الرابط إلى مستودع جيثب في نهاية المقالة.
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. نقوم بإنشاء الهيكل العظمي لقاعدة البيانات الخاصة بنا، أوامر SQL الأولى باستخدام أمثلة java.sql.  - 4
  • Class.forName()يقوم بتحميل الفصل وتسجيله في DriverManager؛
  • DriverManager.getConnection()سيعود Connection- اتصال بقاعدة البيانات المحددة في وسيطة الطريقة واستخدام برنامج تشغيل JDBC المقابل (الذي تم تحميله باستخدام Class.forName()).
  • createStatement()سيعود إلينا Statementكائنًا يمكننا على أساسه تكوين استعلامات لقاعدة البيانات. هناك أيضا:
      CallableStatementلاستدعاء وظائف وإجراءات SQL الخاصة بنظام إدارة قواعد البيانات (يُطلق عليها اسم المخزنة).
    • PreparedStatementتسهيل إنشاء استعلامات ذات معلمات ودفعية.
  • statementسيسمح لك وجود "في متناول اليد" execute()بإرسال طلب في شكل أمر لغة استعلام SQL مباشرة إلى تنفيذ نظام إدارة قواعد البيانات (DBMS) وإرجاع الاستجابة في شكل ResultSet. للراحة هناك:
    • executeQuery()– لقراءة البيانات من نظام إدارة قواعد البيانات (DBMS).
    • executeUpdate()- لتعديل البيانات في نظام إدارة قواعد البيانات (DBMS).
  • يمكن معالجة استجابة الخادم نفسها ResultSetفي النموذج من خلال التكرار عبر first()و last()و next()وما إلى ذلك. يمكننا الحصول على حقول النتائج الفردية من خلال الحروف: getInteger()، getString()...
يجب أن يؤخذ في الاعتبار أنه بعد العمل مع نظام إدارة قواعد البيانات، ومن أجل توفير الموارد، يُنصح بإغلاق الكائنات الموجودة خلفك (بالترتيب الصحيح!) وحفظ ResultSetالموارد . تذكر أنه عند إغلاق كائن أعلى في التسلسل في الرسم التخطيطي، فسوف تقوم بإغلاق جميع الكائنات التي تم إنشاؤها في عملية العمل معه بشكل متتالي. وبالتالي فإن إغلاق الاتصال سيؤدي إلى إغلاق كل ما تم تلقيه بمساعدتهم. StatementConnectionStatementResultSet

تنفيذ المستودع

بعد الجزء النظري من JDBC، دعنا ننتقل إلى تنفيذ المستودع. ونقوم بتنفيذه معمارياً على النحو التالي:
  • سنقوم بنقل الأجزاء الأكثر عمومية من العمل مع نظام إدارة قواعد البيانات (DBMS) إلى سلف مشترك - BaseTable؛
  • سيتم الإعلان عن العمليات المنطقية التي سنقوم بها في الواجهة TableOperation؛
الجزء 3. نقوم بإنشاء الهيكل العظمي لقاعدة البيانات الخاصة بنا، أوامر SQL الأولى باستخدام أمثلة java.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");

    }
}
تتوفر قوائم المستودعات الأخرى والفئة الأصلية عبر الرابط إلى مستودع جيثب في نهاية المقالة. بالطبع، يمكنك إجراء تصميم برنامج مختلف أو إعادة هيكلة أكثر شمولاً للبرنامج: نقل الأجزاء المشتركة إلى فئة الأصل، وتسليط الضوء على الأساليب الشائعة، وما إلى ذلك. لكن الهدف الرئيسي لسلسلة المقالات هو العمل مباشرة مع قاعدة البيانات، لذلك إذا كنت ترغب في ذلك، يمكنك تصميم البرنامج وما شابه ذلك، يمكنك القيام بذلك بنفسك. هيكل المشروع الحالي: الجزء 3. نقوم بإنشاء الهيكل العظمي لقاعدة البيانات الخاصة بنا، أوامر SQL الأولى باستخدام أمثلة java.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. نقوم بإنشاء الهيكل العظمي لقاعدة البيانات الخاصة بنا، أوامر SQL الأولى باستخدام أمثلة java.sql.  - 7

ملخص

وفي الجزأين الثاني والثالث من المقال تعلمنا:
  • أنواع بيانات SQL.
  • جداول قاعدة البيانات.
  • تصميم قاعدة بيانات: هياكل الجدول والعلاقات بينها.
  • لغة الاستعلام SQL من حيث إنشاء جداول قاعدة البيانات ووضع القيود على الحقول والعلاقات بين الجداول.
  • المزيد عن التفاعل مع JDBC.
  • بنية نموذجية/مستودع/خدمة ثلاثية الطبقات (ثلاثية الطبقات) لتطبيق معالجة البيانات.

روابط مفيدة

تعليقات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION