Bagian pertama Bagian kedua
aplikasi jawa
organisasi 3 tingkat
Mari kembali ke aplikasi Java. Versi dari bagian sebelumnya dibuat dalam gaya HelloWorld untuk mengontrol kebenaran tindakan awal. Kami menerapkan arsitektur tiga tingkat (three-layer), yang dalam literatur berbahasa Inggris sering disebut 3tier/3layer . Esensi singkatnya adalah sebagai berikut:- Semua entitas dirancang sebagai model. Ini adalah objek yang berisi:
- Satu set atribut (bidang pribadi kelas).
- Konstruktor.
- Setter dan getter untuk mengatur/membaca atribut.
- Penting agar kode tersebut tidak mengandung kode lain selain yang di atas. Objek seperti ini sering disebut POJO (Plain Old Java Object).
- Semua logika untuk bekerja dengan model diimplementasikan oleh lapisan Layanan. Ini menghasilkan aturan bisnis untuk model. Misalnya memproses permintaan dari aplikasi Java. Argumen kueri dan hasil yang dikembalikan sering kali menyertakan model (atau kumpulannya).
- Lapisan Repositori adalah “perantara” antara DBMS dan Layanan, yang bekerja langsung dengan database dan bertanggung jawab untuk berinteraksi dengannya.
Model
Semua entitas kami (saham, pedagang, kurs, dan tindakan pedagang) dan tabel setaranya memiliki fitur yang sama - kunci primer buatan. Oleh karena itu, mari kita buat kelas dasarBaseModel
. Semua model akan mewarisinya.
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 ini adalah contoh model stok. Anda dapat melihat daftar model lainnya dengan mengikuti tautan ke repositori github di akhir 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 bagian pertama, kita mempelajari cara membuat koneksi ke database dan menutupnya. Sekarang mari kita lanjutkan. Tahapan pengerjaan JDBC ditunjukkan pada diagram berikut:Class.forName()
memuat kelas dan mendaftarkannya ke DriverManager;DriverManager.getConnection()
akan kembaliConnection
– koneksi ke database yang ditentukan dalam argumen metode dan menggunakan driver JDBC yang sesuai (yang dimuat menggunakanClass.forName()
).createStatement()
akan mengembalikan kepada kitaStatement
sebuah objek yang menjadi dasar kita dapat membentuk kueri ke database. Ada juga:PreparedStatement
memfasilitasi pembuatan kueri berparameter dan batch.
CallableStatement
untuk memanggil fungsi dan prosedur SQL DBMS sendiri (disebut tersimpan).- Memiliki "di tangan"
statement
akanexecute()
memungkinkan Anda mengirim permintaan dalam bentuk perintah bahasa query SQL langsung ke eksekusi DBMS dan mengembalikan respons dalam bentukResultSet
. Untuk kenyamanan ada:executeQuery()
– untuk membaca data dari DBMS.
executeUpdate()
– untuk mengubah data di DBMS. - Respon server sendiri
ResultSet
dapat diproses dalam bentuk dengan melakukan iterasi melaluifirst()
,last()
,next()
dan seterusnya. Kita bisa mendapatkan bidang hasil individual melalui pengambil:getInteger()
,getString()
...
ResultSet
, Statement
dan Connection
untuk menghemat sumber daya. Ingat, saat menutup objek yang urutannya lebih tinggi pada diagram, Anda akan menutup semua objek yang dihasilkan dalam proses pengerjaannya. Jadi, menutup koneksi akan menyebabkan penutupan semuanya Statement
dan semua ResultSet
yang diterima dengan bantuan mereka.
Implementasi Repositori
Setelah bagian teoretis JDBC, mari beralih ke implementasi repositori. Kami menerapkannya secara arsitektur sebagai berikut:- Kami akan memindahkan bagian paling umum dari bekerja dengan DBMS ke dalam nenek moyang yang sama -
BaseTable
; - Operasi logika yang akan kita lakukan akan dideklarasikan di antarmuka
TableOperation
;
BaseTable
dan mengimplementasikan antarmuka TableOperation
. Oleh karena itu, kita perlu menulis implementasi metode yang dideklarasikan di antarmuka TableOperation
. Dalam hal ini, kita dapat menggunakan metode kelas induk BaseTable
. Saat ini, antarmuka mendeklarasikan metode untuk membuat tabel:
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; // создание дополнительных правил для значений полей таблиц
}
Saat Anda mempelajari materi, daftar deklarasi metode akan bertambah ( read()
, update()
….). Kami akan menerapkan fitur baru dalam dua langkah:
- Mari tambahkan kemampuan lain untuk bekerja dengan tabel dalam bentuk metode antarmuka baru.
- Selanjutnya, di kelas implementasi antarmuka, kami akan menjelaskan implementasi perangkat lunak dalam metode baru yang dihasilkan oleh antarmuka.
Share
(saham). Logika utamanya ada pada perintah untuk membuat tabel, menentukan tipe data SQL untuk bidang dan menambahkan batasan:
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");
}
}
Daftar repositori lain dan kelas induk tersedia melalui tautan ke repositori github di akhir artikel. Tentu saja, Anda dapat melakukan desain program yang berbeda atau pemfaktoran ulang program yang lebih menyeluruh: memindahkan bagian-bagian umum ke kelas induk, menyorot metode umum, dan sebagainya. Namun tujuan utama dari rangkaian artikel ini adalah untuk langsung bekerja dengan database, jadi jika mau, Anda bisa mendesain program dan sejenisnya, Anda bisa melakukannya sendiri. Struktur proyek saat ini: Selain repositori dan model, kami juga telah membuat kelas StockExchangeDB
untuk manajemen umum emulasi kami. Pada tahap ini kami mengelola repositori (di bagian selanjutnya kami akan beralih ke layanan). Kami mendeklarasikannya dan mulai membuat tabel:
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 драйвер для СУБД не найден!");
}
}
}
Hasil eksekusi:
Ringkasan
Di bagian kedua dan ketiga artikel ini kita mempelajari:- Tipe data SQL.
- Tabel basis data.
- Merancang database: struktur tabel dan hubungan di antara mereka.
- Bahasa query SQL dalam hal pembuatan tabel database, pengaturan batasan field dan hubungan antar tabel.
- Lebih lanjut tentang interaksi dengan JDBC.
- Arsitektur Model/Repositori/Layanan tiga tingkat (tiga lapis) dari aplikasi pemrosesan data.
GO TO FULL VERSION