Birinci hissə İkinci hissə
Hissə 3. Biz verilənlər bazamızın skeletini, ilk SQL əmrlərini java.sql nümunələrindən istifadə edərək yaradırıq.  - 1

Java proqramı

3 səviyyəli təşkilat

Java proqramına qayıdaq. Əvvəlki hissədən olan versiya ilkin hərəkətlərin düzgünlüyünə nəzarət etmək üçün HelloWorld üslubunda yaradılmışdır . Biz ingilisdilli ədəbiyyatda tez-tez 3tier/3layer adlanan üç səviyyəli (üç qatlı) arxitektura tətbiq edirik . Onun qısa mahiyyəti belədir:
  • Bütün obyektlər model kimi hazırlanmışdır. Bunlar ehtiva edən obyektlərdir:
    • Atributlar dəsti (sinfin özəl sahələri).
    • Konstruktor(lar).
    • Atributları təyin etmək/oxumaq üçün təyin edənlər və alıcılar.
    • Onların yuxarıdakılardan başqa heç bir kodun olmaması vacibdir. Belə obyektlər çox vaxt POJO (Plain Old Java Object) adlanır .
  • Modellərlə işləmək üçün bütün məntiq Xidmət səviyyəsi tərəfindən həyata keçirilir. Modellər üçün iş qaydalarını yaradır. Məsələn, Java proqramından gələn sorğuların işlənməsi. Sorğu arqumentləri və qaytarılmış nəticələr çox vaxt modelləri (və ya onların kolleksiyalarını) ehtiva edir.
  • Repository təbəqəsi verilənlər bazası ilə birbaşa işləyən və onunla qarşılıqlı əlaqəyə cavabdeh olan DBMS və Xidmət arasında "vasitəçidir".
Hissə 3. Biz verilənlər bazamızın skeletini, ilk SQL əmrlərini java.sql nümunələrindən istifadə edərək yaradırıq.  - 2 Niyə belə bir konqlomerat yaratmağa ehtiyacımız var? Fakt budur ki, hər bir təbəqə digərlərindən maksimum şəkildə təcrid olunur. Əgər verilənlər bazası əvəzinə mətn faylları toplusumuz varsa, onda kodun qalan hissəsinə toxunmadan yalnız Repozitoriyanın həyata keçirilməsini dəyişdirməliyik . Eynilə, biz minimal dəyişikliklərlə başqa bir Xidmətə qoşula/əlavə edə bilərik . Böyük sistemlər üçün müxtəlif təbəqələrin həyata keçirilməsini müxtəlif insanlara verə və ya müxtəlif təbəqələrin optimal tətbiqlərini birləşdirərək təcrübə edə bilərik. Tətbiqimiz üçün müvafiq siniflərin yerləşəcəyi model , repozitoriya , xidmət paketləri yaradaq . Növbəti hissələrdə Xidmət qatına qayıdacayıq, lakin hələlik modellərə və depolara diqqət yetirəcəyik. Hissə 3. Biz verilənlər bazamızın skeletini, ilk SQL əmrlərini java.sql nümunələrindən istifadə edərək yaradırıq.  - 3

Model

Bütün qurumlarımız (səhmlər, treyderlər, tariflər və treyderlərin hərəkətləri) və onların cədvəl ekvivalentləri ümumi xüsusiyyətə malikdir - süni əsas açar. Buna görə də, əsas sinif yaradaq BaseModel. Bütün modellər ondan miras qalacaq.
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);
    }
}
Aşağıda bir stok modeli nümunəsidir. Qalan model siyahıları ilə məqalənin sonundakı github deposuna keçidə daxil olaraq baxa bilərsiniz.
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

Birinci hissədə verilənlər bazası ilə əlaqə qurmağı və onu bağlamağı öyrəndik. İndi davam edək. JDBC ilə işin mərhələləri aşağıdakı diaqramda göstərilmişdir: Hissə 3. Biz verilənlər bazamızın skeletini, ilk SQL əmrlərini java.sql nümunələrindən istifadə edərək yaradırıq.  - 4
  • Class.forName()sinfi yükləyir və DriverManager-də qeyd edir;
  • DriverManager.getConnection()qayıdacaq Connection– metod arqumentində göstərilən verilənlər bazası ilə əlaqə və müvafiq JDBC sürücüsündən istifadə etməklə (istifadə edərək yüklənmişdir Class.forName()).
  • createStatement()bizə bir obyekti qaytaracaq, Statementonun əsasında verilənlər bazasına sorğular yarada bilərik. Həmçinin var:
      CallableStatementDBMS-nin öz SQL funksiyalarını və prosedurlarını çağırmaq üçün (onlar saxlanılan adlanır).
    • PreparedStatementparametrləşdirilmiş və toplu sorğuların yaradılmasını asanlaşdırmaq.
  • “Əldə” olması sizə SQL sorğu dili əmri şəklində sorğunu birbaşa DBMS icrasına göndərməyə və şəklində cavab qaytarmağa imkan statementverəcək . Rahatlıq üçün bunlar var: execute()ResultSet
    • executeQuery()– DBMS-dən məlumatları oxumaq üçün.
    • executeUpdate()– DBMS-dəki məlumatları dəyişdirmək üçün.
  • Server cavabının özü, , və s. ResultSetvasitəsilə təkrarlanaraq formada işlənə bilər . Alıcılar vasitəsilə fərdi nəticələr sahələri əldə edə bilərik: , ...first()last()next()getInteger()getString()
Nəzərə almaq lazımdır ki, DBMS ilə işlədikdən sonra resurslara qənaət etmək üçün arxanızdakı obyektləri bağlamaq (düzgün ardıcıllıqla!) ResultSet, resurslara qənaət etmək məsləhətdir . Unutmayın ki, diaqramdakı ardıcıllıqla daha yüksək olan bir obyekti bağlayarkən, onunla işləmə prosesində yaranan bütün obyektləri kaskadla bağlayacaqsınız. Beləliklə, bir əlaqənin bağlanması hamısının bağlanmasına səbəb olacaq və hamısı onların köməyi ilə alınacaq. StatementConnectionStatementResultSet

Repozitoriyanın həyata keçirilməsi

Nəzəri JDBC hissəsindən sonra anbarın həyata keçirilməsinə keçək. Biz onu memarlıq baxımından aşağıdakı kimi həyata keçiririk:
  • DBMS ilə işləməyin ən ümumi hissələrini ümumi əcdada keçirəcəyik - BaseTable;
  • İcra edəcəyimiz məntiqi əməliyyatlar interfeysdə elan ediləcək TableOperation;
Hissə 3. Biz verilənlər bazamızın skeletini, ilk SQL əmrlərini java.sql nümunələrindən istifadə edərək yaradırıq.  - 5 Yeni repozitoriya sinifdən miras alacaq BaseTablevə interfeysi həyata keçirəcək TableOperation. Beləliklə, interfeysdə elan edilmiş metodların həyata keçirilməsini yazmalıyıq TableOperation. Bu halda biz ana sinifin metodlarından istifadə edə bilərik BaseTable. Hal-hazırda interfeys cədvəllərin yaradılması üsullarını elan edir:
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; // создание дополнительных правил для значений полей таблиц
}
Materialı öyrəndikcə metod bəyannamələrinin siyahısı genişlənəcək ( read(), update()....). Yeni funksiyaları iki addımda tətbiq edəcəyik:
  1. Yeni interfeys metodu şəklində cədvəllə işləmək üçün başqa bir qabiliyyət əlavə edək.
  2. Sonra interfeysi həyata keçirən siniflərdə proqram təminatının interfeys tərəfindən yaradılan yeni metodlarda tətbiqini təsvir edəcəyik.
Share(səhmlər) üçün nümunə depo . Əsas məntiq cədvəllər yaratmaq, sahələr üçün SQL məlumat növlərini təyin etmək və məhdudiyyətlər əlavə etmək əmrlərindədir:
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");

    }
}
Digər repozitoriyaların və ana sinifin siyahıları məqalənin sonundakı github repozitoriyasına keçid vasitəsilə əldə edilə bilər. Əlbəttə ki, siz fərqli proqram dizaynını və ya proqramın daha əsaslı refaktorinqini edə bilərsiniz: ümumi hissələri ana sinifə köçürün, ümumi metodları vurğulayın və s. Amma məqalələr silsiləsinin əsas məqsədi bilavasitə verilənlər bazası ilə işləməkdir, ona görə də istəsəniz, proqramı və buna bənzəri dizayn edə bilərsiniz, özünüz edə bilərsiniz. Cari layihə strukturu: Depolar və modellərə əlavə olaraq, biz emulyasiyamızın ümumi idarə edilməsi üçün Hissə 3. Biz verilənlər bazamızın skeletini, ilk SQL əmrlərini java.sql nümunələrindən istifadə edərək yaradırıq.  - 6 əlavə olaraq bir sinif yaratdıq . StockExchangeDBBu mərhələdə biz depoları idarə edirik (növbəti hissələrdə xidmətlərə keçəcəyik). Onları elan edirik və cədvəllər yaratmağa başlayırıq:
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 драйвер для СУБД не найден!");
        }
    }
}
İcra nəticəsi: Hissə 3. Biz verilənlər bazamızın skeletini, ilk SQL əmrlərini java.sql nümunələrindən istifadə edərək yaradırıq.  - 7

Xülasə

Məqalənin ikinci və üçüncü hissələrində öyrəndik:
  • SQL məlumat növləri.
  • Verilənlər bazası cədvəlləri.
  • Verilənlər bazasının layihələndirilməsi: cədvəl strukturları və onlar arasında əlaqələr.
  • Verilənlər bazası cədvəllərinin yaradılması, sahələrə məhdudiyyətlərin qoyulması və cədvəllər arasında əlaqələr baxımından SQL sorğu dili.
  • JDBC ilə qarşılıqlı əlaqə haqqında daha çox.
  • Məlumat emalı proqramının üç səviyyəli (üç qatlı) Model/Repository/Xidmət arxitekturası.

faydalı bağlantılar