JavaRush /בלוג Java /Random-HE /חלק 3. אנו יוצרים את השלד של מסד הנתונים שלנו, פקודות SQL...
Marat Sadykov
רָמָה

חלק 3. אנו יוצרים את השלד של מסד הנתונים שלנו, פקודות SQL הראשונות באמצעות דוגמאות java.sql.

פורסם בקבוצה
חלק ראשון חלק שני
חלק 3. אנו יוצרים את השלד של מסד הנתונים שלנו, פקודות SQL הראשונות באמצעות דוגמאות java.sql.  - 1

אפליקציית Java

ארגון 3 שכבות

בואו נחזור לאפליקציית Java. הגרסה מהחלק הקודם נוצרה בסגנון HelloWorld כדי לשלוט בנכונות הפעולות הראשוניות. אנו מיישמים ארכיטקטורה תלת-שכבתית (תלת-שכבתית), אשר בספרות באנגלית נקראת לרוב 3tier/3layer . המהות הקצרה שלו היא כדלקמן:
  • כל הישויות מעוצבות כמודלים. אלו הם אובייקטים המכילים:
    • קבוצה של תכונות (שדות פרטיים של הכיתה).
    • קונסטרוקטור(ים).
    • מגדירים וגטרים להגדרה/קריאה של תכונות.
    • חשוב שהם לא יכילו שום קוד אחר מלבד האמור לעיל. אובייקטים כאלה נקראים לעתים קרובות POJO (Plain Old Java Object).
  • כל ההיגיון לעבודה עם מודלים מיושם על ידי שכבת השירות. זה מייצר כללים עסקיים לדוגמניות. לדוגמה, עיבוד בקשות מאפליקציית Java. ארגומנטים של שאילתה ותוצאות שהוחזרו כוללים לרוב מודלים (או אוספים שלהם).
  • שכבת המאגר היא "מתווכת" בין ה-DBMS לשירות, עובדת ישירות עם מסד הנתונים ואחראית על האינטראקציה איתו.
חלק 3. אנו יוצרים את השלד של מסד הנתונים שלנו, פקודות SQL הראשונות באמצעות דוגמאות java.sql.  - 2 למה אנחנו בכלל צריכים להקים קונגלומרט כזה? העובדה היא שכל שכבה מבודדת בצורה מקסימלית מהאחרות. אם במקום מסד נתונים יש לנו סט של קבצי טקסט, אז אנחנו צריכים רק לשנות את היישום של Repository מבלי לגעת בשאר הקוד. באופן דומה, אנו יכולים לחבר/להוסיף שירות נוסף במינימום שינויים. עבור מערכות גדולות, נוכל לתת הטמעה של שכבות שונות לאנשים שונים או להתנסות על ידי שילוב של יישומים אופטימליים של שכבות שונות. בואו ניצור מודל חבילות , מאגר , שירות עבור האפליקציה שלנו, היכן ימוקמו המחלקות המתאימות. נחזור לשכבת השירות בחלקים הבאים, אך לעת עתה נשים לב לדגמים ולמאגרים. חלק 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);
    }
}
להלן מודל מניות לדוגמה. אתה יכול לראות את שאר רשימות הדגמים על ידי לחיצה על הקישור למאגר 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 מוצגים בתרשים הבא: חלק 3. אנו יוצרים את השלד של מסד הנתונים שלנו, פקודות SQL הראשונות באמצעות דוגמאות java.sql.  - 4
  • Class.forName()טוען את המחלקה ורושם אותה ב-DriverManager;
  • DriverManager.getConnection()יחזור Connection- חיבור למסד הנתונים שצוין בארגומנט המתודה ובאמצעות מנהל ההתקן JDBC המתאים (שנטען באמצעות Class.forName()).
  • createStatement()יחזיר לנו Statementאובייקט שעל בסיסו נוכל ליצור שאילתות למסד הנתונים. יש גם:
      CallableStatementלקרוא לפונקציות והנהלים של SQL של ​​ה-DBMS (הם נקראים מאוחסנים).
    • PreparedStatementהקלה על יצירת שאילתות עם פרמטרים ושאילתות אצווה.
  • קבלת "ביד" statementתאפשר execute()לך לשלוח בקשה בצורה של פקודת שפת שאילתה של SQL ישירות לביצוע DBMS ולהחזיר תגובה בצורה של ResultSet. לנוחות יש:
    • executeQuery()– לקריאת נתונים מה-DBMS.
    • executeUpdate()- כדי לשנות נתונים ב-DBMS.
  • ניתן לעבד את תגובת השרת עצמו ResultSetבצורה על ידי איטרציה דרך first(), last(), next()וכן הלאה. אנו יכולים לקבל שדות תוצאות בודדים באמצעות מגברים: getInteger(), getString()...
יש לזכור כי לאחר העבודה עם ה-DBMS, על מנת לחסוך במשאבים, רצוי לסגור את האובייקטים מאחוריכם (בסדר הנכון!) ResultSet, Statementולחסוך Connectionבמשאבים. זכרו, בעת סגירת אובייקט גבוה יותר ברצף בתרשים, תסגרו את כל האובייקטים שנוצרו בתהליך העבודה איתו. לפיכך, סגירת קשר תוביל לסגירה של כולו Statementוכל ResultSetהמתקבלים בעזרתם.

יישום מאגר

לאחר החלק התיאורטי של 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");

    }
}
רישומים של מאגרים אחרים ושל מחלקת האב זמינים דרך הקישור למאגר github בסוף המאמר. כמובן, אתה יכול לעשות עיצוב אחר של התוכנית או שינוי יסודי יותר של התוכנית: להעביר חלקים משותפים למחלקה אב, להדגיש שיטות נפוצות, וכן הלאה. אבל המטרה העיקרית של סדרת המאמרים היא עבודה ישירה עם בסיס הנתונים, כך שאם תרצו, תוכלו לעצב את התוכנה וכדומה, תוכלו לעשות זאת בעצמכם. מבנה הפרויקט הנוכחי: חלק 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