Биринчи бөлүк Экинчи бөлүк
Java колдонмосу
3 баскычтуу уюм
Келгиле, Java колдонмосуна кайтып келели. Мурунку бөлүктөгү version баштапкы аракеттердин тууралыгын көзөмөлдөө үчүн HelloWorld стorнде түзүлгөн. Биз англис тилдүү адабияттарда көбүнчө 3tier/3layer деп аталган үч катмарлуу (үч катмарлуу) архитектураны ишке ашырабыз . Анын кыскача маңызы төмөнкүдөй:- Бардык an objectтер үлгү катары иштелип чыккан. Булар төмөнкүлөрдү камтыган an objectилер:
- Атрибуттардын жыйындысы (класстын жеке талаалары).
- Конструктор(лар).
- Атрибуттарды орнотуу/окуу үчүн орнотуучулар жана алуучулар.
- Аларда жогоруда айтылгандардан башка эч кандай code болбошу маанилүү. Мындай an objectтер көбүнчө POJO (Plain Old Java Object) деп аталат .
- Моделдер менен иштөөнүн бардык логикасы Сервис катмары тарабынан ишке ашырылат. Бул моделдер үчүн бизнес эрежелерин түзөт. Мисалы, Java тиркемесинин суроо-талаптарын иштетүү. Суроо аргументтери жана кайтарылган натыйжалар көбүнчө моделдерди (же алардын жыйнактарын) камтыйт.
- Репозиторий катмары ДББ жана Кызматтын ортосундагы “ортомчу” болуп саналат, маалымат базасы менен түздөн-түз иштейт жана аны менен өз ара аракеттенүүгө жооптуу.
Модел
Биздин бардык субъектилер (акциялар, трейдерлер, тарифтер жана трейдерлердин аракеттери) жана алардын 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 менен иштөө этаптары төмөнкү диаграммада көрсөтүлгөн:Class.forName()
классты жүктөйт жана аны DriverManager менен каттайт;DriverManager.getConnection()
кайтып келетConnection
– метод аргументинде көрсөтүлгөн маалымат базасына туташуу жана тиешелүү JDBC драйверин колдонуу (колдонуу менен жүктөлгөнClass.forName()
).createStatement()
бизгеStatement
an objectти кайтарып берет, анын негизинде биз маалымат базасына суроо түзө алабыз. Ошондой эле бар:PreparedStatement
параметрлештирилген жана пакеттик сурамдарды түзүүгө көмөктөшөт.
CallableStatement
DBMS өзүнүн SQL функцияларын жана proceduresаларын чакыруу үчүн (алар сакталган деп аталат).- "Колунда" болуу сизге SQL суроо тorнин буйругу түрүндө суроо-талапты түздөн-түз DBMS аткаруусуна жөнөтүүгө жана түрүндө жооп кайтарууга мүмкүндүк
statement
берет . Ыңгайлуулук үчүн төмөнкүлөр бар:execute()
ResultSet
executeQuery()
– МББдан маалыматтарды окуу үчүн.
executeUpdate()
– МББдагы маалыматтарды өзгөртүү үчүн. - Сервердин жообу , , ж.б. аркылуу
ResultSet
кайталоо аркылуу формада иштетorши мүмкүн . Биз алуучулар аркылуу жеке натыйжа талааларын ала алабыз: , ...first()
last()
next()
getInteger()
getString()
ResultSet
ресурстарды үнөмдөө максатка ылайыктуу экенин эстен чыгарбоо керек . Эсиңизде болсун, диаграммадагы ырааттуулукта жогору турган an objectти жабууда сиз аны менен иштөө процессинде пайда болгон бардык an objectтерди каскаддык жабасыз. Ошентип, байланышты жабуу анын баарын жабууга алып келет жана алардын жардамы менен алынган. Statement
Connection
Statement
ResultSet
Репозиторийди ишке ашыруу
Теориялык JDBC бөлүгүнөн кийин репозиторийди ишке ашырууга өтөбүз. Биз аны архитектуралык жактан төмөнкүдөй ишке ашырабыз:- Биз ДББ менен иштөөнүн эң жалпы бөлүктөрүн жалпы ата-бабага көчүрөбүз -
BaseTable
; - Биз аткара турган логикалык операциялар интерфейсте жарыяланат
TableOperation
;
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()
….). Жаңы функцияларды эки кадам менен ишке ашырабыз:
- Жаңы интерфейс ыкмасы түрүндө table менен иштөөнүн дагы бир жөндөмүн кошолу.
- Андан ары интерфейсти ишке ашыруучу класстарда программалык камсыздоону интерфейс тарабынан түзүлгөн жаңы методдордо ишке ашырууну сүрөттөп беребиз.
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ктүү. Албетте, сиз программанын башка дизайнын же программанын кылдат рефакторингин жасай аласыз: жалпы бөлүктөрдү ата-эне класска жылдыруу, жалпы ыкмаларды бөлүп көрсөтүү ж.б.у.с. Бирок макалалар сериясынын негизги максаты – маалымат базасы менен түздөн-түз иштөө, андыктан сиз кааласаңыз, программаны жана башкаларды иштеп чыга аласыз, аны өзүңүз жасай аласыз. Учурдагы долбоордун структурасы: Репозиторийлерден жана моделдерден тышкары, биз 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 драйвер для СУБД не найден!");
}
}
}
Аткаруу натыйжасы:
Жыйынтык
Макаланын экинчи жана үчүнчү бөлүктөрүндө биз билдик:- SQL маалымат түрлөрү.
- Берorштер базасы tableлары.
- Маалыматтар базасын долбоорлоо: table структуралары жана алардын ортосундагы мамилелер.
- Маалыматтар базасынын tableларын түзүү, талааларга чектөөлөрдү коюу жана tableлардын ортосундагы мамилелер жагынан SQL суроо тor.
- JDBC менен өз ара аракеттенүү жөнүндө көбүрөөк.
- Маалыматтарды иштетүүчү тиркеменин үч баскычтуу (үч катмарлуу) модели/репозиторий/кызмат архитектурасы.
GO TO FULL VERSION