Bahagian pertama Bahagian kedua
Aplikasi Java
organisasi 3 peringkat
Mari kembali ke aplikasi Java. Versi dari bahagian sebelumnya telah dibuat dalam gaya HelloWorld untuk mengawal ketepatan tindakan awal. Kami melaksanakan seni bina tiga peringkat (tiga lapisan), yang dalam kesusasteraan bahasa Inggeris sering dipanggil 3tier/3layer . Intipati ringkasnya adalah seperti berikut:- Semua entiti direka bentuk sebagai model. Ini adalah objek yang mengandungi:
- Satu set atribut (medan peribadi kelas).
- Pembina.
- Setter dan getter untuk menetapkan/membaca atribut.
- Adalah penting bahawa ia tidak mengandungi sebarang kod lain selain daripada di atas. Objek sebegini sering dipanggil POJO (Plain Old Java Object).
- Semua logik untuk bekerja dengan model dilaksanakan oleh lapisan Perkhidmatan. Ia menjana peraturan perniagaan untuk model. Contohnya, memproses permintaan daripada aplikasi Java. Argumen pertanyaan dan hasil yang dikembalikan selalunya termasuk model (atau koleksinya).
- Lapisan Repositori ialah "perantara" antara DBMS dan Perkhidmatan, bekerja secara langsung dengan pangkalan data dan bertanggungjawab untuk interaksi dengannya.
Model
Semua entiti kami (saham, peniaga, kadar dan tindakan pedagang) dan setara jadual mereka mempunyai ciri yang sama - kunci utama tiruan. Oleh itu, mari kita buat kelas asasBaseModel
. Semua model akan mewarisi daripadanya.
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);
}
}
Di bawah adalah contoh model saham. Anda boleh melihat senarai model yang lain dengan mengikuti pautan ke repositori github di penghujung artikel.
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
Pada bahagian pertama, kami belajar cara mewujudkan sambungan ke pangkalan data dan menutupnya. Sekarang mari kita teruskan. Peringkat bekerja dengan JDBC ditunjukkan dalam rajah berikut:Class.forName()
memuatkan kelas dan mendaftarkannya dengan DriverManager;DriverManager.getConnection()
akan kembaliConnection
– sambungan ke pangkalan data yang dinyatakan dalam hujah kaedah dan menggunakan pemacu JDBC yang sepadan (yang dimuatkan menggunakanClass.forName()
).createStatement()
akan mengembalikan kepada kamiStatement
objek yang berdasarkannya kami boleh membentuk pertanyaan kepada pangkalan data. Terdapat juga:PreparedStatement
memudahkan penciptaan pertanyaan berparameter dan kelompok.
CallableStatement
untuk memanggil fungsi dan prosedur SQL DBMS sendiri (ia dipanggil disimpan).- Mempunyai "di tangan"
statement
akanexecute()
membolehkan anda menghantar permintaan dalam bentuk perintah bahasa pertanyaan SQL terus ke pelaksanaan DBMS dan mengembalikan respons dalam bentukResultSet
. Untuk kemudahan terdapat:executeQuery()
– untuk membaca data daripada DBMS.
executeUpdate()
– untuk mengubah suai data dalam DBMS. - Sambutan pelayan itu sendiri
ResultSet
boleh diproses dalam bentuk dengan mengulangifirst()
,last()
,next()
dan seterusnya. Kita boleh mendapatkan medan hasil individu melalui pengambil:getInteger()
,getString()
...
ResultSet
, Statement
dan Connection
untuk menjimatkan sumber. Ingat, apabila menutup objek yang lebih tinggi dalam jujukan pada rajah, anda akan menutup semua objek yang dijana dalam proses bekerja dengannya. Oleh itu, menutup sambungan akan membawa kepada penutupan semua itu Statement
dan semua ResultSet
diterima dengan bantuan mereka.
Pelaksanaan Repositori
Selepas bahagian JDBC teori, mari kita beralih kepada pelaksanaan repositori. Kami melaksanakannya secara seni bina seperti berikut:- Kami akan memindahkan bahagian yang paling umum bekerja dengan DBMS ke dalam nenek moyang yang sama -
BaseTable
; - Operasi logik yang akan kami lakukan akan diisytiharkan dalam antara muka
TableOperation
;
BaseTable
dan melaksanakan antara muka TableOperation
. Oleh itu, kita perlu menulis pelaksanaan kaedah yang diisytiharkan dalam antara muka TableOperation
. Dalam kes ini, kita boleh menggunakan kaedah kelas induk BaseTable
. Pada masa ini, antara muka mengisytiharkan kaedah untuk membuat jadual:
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; // создание дополнительных правил для значений полей таблиц
}
Semasa anda mengkaji bahan, senarai pengisytiharan kaedah akan berkembang ( read()
, update()
….). Kami akan melaksanakan ciri baharu dalam dua langkah:
- Mari tambah satu lagi keupayaan untuk bekerja dengan jadual dalam bentuk kaedah antara muka baharu.
- Seterusnya, dalam kelas yang melaksanakan antara muka, kami akan menerangkan pelaksanaan perisian dalam kaedah baharu yang dihasilkan oleh antara muka.
Share
(stok). Logik utama adalah dalam arahan untuk membuat jadual, menentukan jenis data SQL untuk medan dan menambah sekatan:
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");
}
}
Penyenaraian repositori lain dan kelas induk tersedia melalui pautan ke repositori github pada akhir artikel. Sudah tentu, anda boleh melakukan reka bentuk program yang berbeza atau pemfaktoran semula program yang lebih teliti: memindahkan bahagian biasa ke dalam kelas induk, menyerlahkan kaedah biasa, dan sebagainya. Tetapi matlamat utama siri artikel adalah untuk bekerja secara langsung dengan pangkalan data, jadi jika anda mahu, anda boleh mereka bentuk program dan sebagainya, anda boleh melakukannya sendiri. Struktur projek semasa: Selain repositori dan model, kami juga telah mencipta kelas StockExchangeDB
untuk pengurusan am emulasi kami. Pada peringkat ini kami menguruskan repositori (di bahagian seterusnya kami akan beralih ke perkhidmatan). Kami mengisytiharkannya dan mula membuat jadual:
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 драйвер для СУБД не найден!");
}
}
}
Keputusan pelaksanaan:
Ringkasan
Dalam bahagian kedua dan ketiga artikel yang kami pelajari:- jenis data SQL.
- Jadual pangkalan data.
- Mereka bentuk pangkalan data: struktur jadual dan hubungan antara mereka.
- Bahasa pertanyaan SQL dari segi mencipta jadual pangkalan data, menetapkan sekatan pada medan dan hubungan antara jadual.
- Lebih lanjut mengenai interaksi dengan JDBC.
- Seni bina Model/Repositori/Perkhidmatan tiga peringkat (tiga lapisan) bagi aplikasi pemprosesan data.
GO TO FULL VERSION