Birinci hissə İkinci hissə
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".
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 yaradaqBaseModel
. 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:Class.forName()
sinfi yükləyir və DriverManager-də qeyd edir;DriverManager.getConnection()
qayıdacaqConnection
– 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şdirClass.forName()
).createStatement()
bizə bir obyekti qaytaracaq,Statement
onun əsasında verilənlər bazasına sorğular yarada bilərik. Həmçinin var:PreparedStatement
parametrləşdirilmiş və toplu sorğuların yaradılmasını asanlaşdırmaq.
CallableStatement
DBMS-nin öz SQL funksiyalarını və prosedurlarını çağırmaq üçün (onlar saxlanılan adlanır).- “Ə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
statement
verə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.
ResultSet
vasitə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()
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. Statement
Connection
Statement
ResultSet
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
;
BaseTable
və 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:
- Yeni interfeys metodu şəklində cədvəllə işləmək üçün başqa bir qabiliyyət əlavə edək.
- 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 əlavə olaraq bir sinif yaratdıq . StockExchangeDB
Bu 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:
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ı.
GO TO FULL VERSION