JavaRush /Java блогу /Random-KY /3-бөлүк. Биз базабыздын скелетин, java.sql мисалдарын кол...
Marat Sadykov
Деңгээл

3-бөлүк. Биз базабыздын скелетин, java.sql мисалдарын колдонуу менен биринчи SQL буйруктарын түзөбүз.

Группада жарыяланган
Биринчи бөлүк Экинчи бөлүк
3-бөлүк. Биз базабыздын скелетин, java.sql мисалдарын колдонуу менен биринчи SQL буйруктарын түзөбүз.  - 1

Java колдонмосу

3 баскычтуу уюм

Келгиле, Java колдонмосуна кайтып келели. Мурунку бөлүктөгү version баштапкы аракеттердин тууралыгын көзөмөлдөө үчүн HelloWorld стorнде түзүлгөн. Биз англис тилдүү адабияттарда көбүнчө 3tier/3layer деп аталган үч катмарлуу (үч катмарлуу) архитектураны ишке ашырабыз . Анын кыскача маңызы төмөнкүдөй:
  • Бардык an objectтер үлгү катары иштелип чыккан. Булар төмөнкүлөрдү камтыган an objectилер:
    • Атрибуттардын жыйындысы (класстын жеке талаалары).
    • Конструктор(лар).
    • Атрибуттарды орнотуу/окуу үчүн орнотуучулар жана алуучулар.
    • Аларда жогоруда айтылгандардан башка эч кандай code болбошу маанилүү. Мындай an objectтер көбүнчө POJO (Plain Old Java Object) деп аталат .
  • Моделдер менен иштөөнүн бардык логикасы Сервис катмары тарабынан ишке ашырылат. Бул моделдер үчүн бизнес эрежелерин түзөт. Мисалы, Java тиркемесинин суроо-талаптарын иштетүү. Суроо аргументтери жана кайтарылган натыйжалар көбүнчө моделдерди (же алардын жыйнактарын) камтыйт.
  • Репозиторий катмары ДББ жана Кызматтын ортосундагы “ортомчу” болуп саналат, маалымат базасы менен түздөн-түз иштейт жана аны менен өз ара аракеттенүүгө жооптуу.
3-бөлүк. Биз базабыздын скелетин, java.sql мисалдарын колдонуу менен биринчи SQL буйруктарын түзөбүз.  - 2 Эмне үчүн бизге ушундай конгломерат түзүү керек? Чындыгында, ар бир катмар башкалардан максималдуу түрдө обочолонгон. Эгерде маалымат базасынын ордуна бизде тексттик файлдардын топтому бар болсо, анда биз codeдун калган бөлүгүнө тийбестен Репозиторийдин ишке ашырылышын өзгөртүүбүз керек . Ошо сыяктуу эле, биз минималдуу өзгөртүүлөр менен башка Кызматты туташтыра алабыз/кошуп алабыз . Чоң системалар үчүн биз ар кандай адамдарга ар кандай катмарларды ишке ашырууну бере алабыз же ар кандай катмарлардын оптималдуу ишке ашырууларын айкалыштыруу менен эксперимент жасай алабыз. Тиешелүү класстар жайгашкан биздин тиркеме үчүн моделдин пакеттерин , репозиторийлерин , сервисин түзөлү . Биз кийинки бөлүктөрдө Кызмат катмарына кайтабыз, бирок азырынча моделдерге жана репозиторийлерге көңүл бурабыз. 3-бөлүк. Биз базабыздын скелетин, java.sql мисалдарын колдонуу менен биринчи SQL буйруктарын түзөбүз.  - 3

Модел

Биздин бардык субъектилер (акциялар, трейдерлер, тарифтер жана трейдерлердин аракеттери) жана алардын tableдагы эквиваленттеринин жалпы өзгөчөлүгү бар - жасалма баштапкы ачкыч. Ошондуктан, келгиле, базалык класс түзөлү 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-бөлүк. Биз базабыздын скелетин, java.sql мисалдарын колдонуу менен биринчи SQL буйруктарын түзөбүз.  - 4
  • Class.forName()классты жүктөйт жана аны DriverManager менен каттайт;
  • DriverManager.getConnection()кайтып келет Connection– метод аргументинде көрсөтүлгөн маалымат базасына туташуу жана тиешелүү JDBC драйверин колдонуу (колдонуу менен жүктөлгөн Class.forName()).
  • createStatement()бизге Statementan objectти кайтарып берет, анын негизинде биз маалымат базасына суроо түзө алабыз. Ошондой эле бар:
      CallableStatementDBMS өзүнүн SQL функцияларын жана proceduresаларын чакыруу үчүн (алар сакталган деп аталат).
    • PreparedStatementпараметрлештирилген жана пакеттик сурамдарды түзүүгө көмөктөшөт.
  • "Колунда" болуу сизге SQL суроо тorнин буйругу түрүндө суроо-талапты түздөн-түз DBMS аткаруусуна жөнөтүүгө жана түрүндө жооп кайтарууга мүмкүндүк statementберет . Ыңгайлуулук үчүн төмөнкүлөр бар: execute()ResultSet
    • executeQuery()– МББдан маалыматтарды окуу үчүн.
    • executeUpdate()– МББдагы маалыматтарды өзгөртүү үчүн.
  • Сервердин жообу , , ж.б. аркылуу ResultSetкайталоо аркылуу формада иштетorши мүмкүн . Биз алуучулар аркылуу жеке натыйжа талааларын ала алабыз: , ...first()last()next()getInteger()getString()
МББ менен иштегенден кийин ресурстарды үнөмдөө үчүн артыңыздагы an objectтерди (туура тартипте!) жабуу жана ResultSetресурстарды үнөмдөө максатка ылайыктуу экенин эстен чыгарбоо керек . Эсиңизде болсун, диаграммадагы ырааттуулукта жогору турган an objectти жабууда сиз аны менен иштөө процессинде пайда болгон бардык an objectтерди каскаддык жабасыз. Ошентип, байланышты жабуу анын баарын жабууга алып келет жана алардын жардамы менен алынган. StatementConnectionStatementResultSet

Репозиторийди ишке ашыруу

Теориялык JDBC бөлүгүнөн кийин репозиторийди ишке ашырууга өтөбүз. Биз аны архитектуралык жактан төмөнкүдөй ишке ашырабыз:
  • Биз ДББ менен иштөөнүн эң жалпы бөлүктөрүн жалпы ата-бабага көчүрөбүз - BaseTable;
  • Биз аткара турган логикалык операциялар интерфейсте жарыяланат TableOperation;
3-бөлүк. Биз базабыздын скелетин, java.sql мисалдарын колдонуу менен биринчи SQL буйруктарын түзөбүз.  - 5 Жаңы репозиторий класстан мурастап BaseTable, интерфейсти ишке ашырат TableOperation. Ошентип, интерфейсте жарыяланган ыкмаларды ишке ашырууну жазышыбыз керек TableOperation. Бул учурда, биз ата-класстын ыкмаларын колдоно алабыз BaseTable. Азыркы учурда, интерфейс tableларды түзүү ыкмаларын жарыялайт:
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. Жаңы интерфейс ыкмасы түрүндө table менен иштөөнүн дагы бир жөндөмүн кошолу.
  2. Андан ары интерфейсти ишке ашыруучу класстарда программалык камсыздоону интерфейс тарабынан түзүлгөн жаңы методдордо ишке ашырууну сүрөттөп беребиз.
Share(акциялар) үчүн репозиторийдин үлгүсү . Негизги логика tableларды түзүү, талаалар үчүн 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 репозиторийине шилтеме аркылуу жеткorктүү. Албетте, сиз программанын башка дизайнын же программанын кылдат рефакторингин жасай аласыз: жалпы бөлүктөрдү ата-эне класска жылдыруу, жалпы ыкмаларды бөлүп көрсөтүү ж.б.у.с. Бирок макалалар сериясынын негизги максаты – маалымат базасы менен түздөн-түз иштөө, андыктан сиз кааласаңыз, программаны жана башкаларды иштеп чыга аласыз, аны өзүңүз жасай аласыз. Учурдагы долбоордун структурасы: 3-бөлүк. Биз базабыздын скелетин, java.sql мисалдарын колдонуу менен биринчи SQL буйруктарын түзөбүз.  - 6 Репозиторийлерден жана моделдерден тышкары, биз StockExchangeDBэмуляциябызды жалпы башкаруу үчүн кошумча класс түздүк. Бул этапта биз репозиторийлерди башкарабыз (кийинки бөлүмдөрдө биз кызматтарга өтөбүз). Биз аларды жарыялап, tableларды түзө баштайбыз:
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 маалымат түрлөрү.
  • Берorштер базасы tableлары.
  • Маалыматтар базасын долбоорлоо: table структуралары жана алардын ортосундагы мамилелер.
  • Маалыматтар базасынын tableларын түзүү, талааларга чектөөлөрдү коюу жана tableлардын ортосундагы мамилелер жагынан SQL суроо тor.
  • JDBC менен өз ара аракеттенүү жөнүндө көбүрөөк.
  • Маалыматтарды иштетүүчү тиркеменин үч баскычтуу (үч катмарлуу) модели/репозиторий/кызмат архитектурасы.

пайдалуу шилтемелер

Комментарийлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION