JavaRush /Blog Java /Random-MS /Bahagian 3. Kami mencipta rangka pangkalan data kami, ara...

Bahagian 3. Kami mencipta rangka pangkalan data kami, arahan SQL pertama menggunakan contoh java.sql.

Diterbitkan dalam kumpulan
Bahagian pertama Bahagian kedua
Bahagian 3. Kami mencipta rangka pangkalan data kami, arahan SQL pertama menggunakan contoh java.sql.  - 1

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.
Bahagian 3. Kami mencipta rangka pangkalan data kami, arahan SQL pertama menggunakan contoh java.sql.  - 2 Mengapa kita perlu membentuk konglomerat sedemikian? Hakikatnya ialah setiap lapisan diasingkan secara maksimum daripada yang lain. Jika bukannya pangkalan data kita mempunyai satu set fail teks, maka kita hanya perlu menukar pelaksanaan Repositori tanpa menyentuh kod yang lain. Begitu juga, kami boleh menyambung/menambah Perkhidmatan lain dengan perubahan yang minimum. Untuk sistem yang besar, kami boleh memberikan pelaksanaan lapisan berbeza kepada orang atau percubaan yang berbeza dengan menggabungkan pelaksanaan optimum lapisan berbeza. Mari buat pakej model , repositori , perkhidmatan untuk aplikasi kami, di mana kelas yang sepadan akan ditempatkan. Kami akan kembali ke lapisan Perkhidmatan di bahagian berikut, tetapi buat masa ini kami akan memberi perhatian kepada model dan repositori. Bahagian 3. Kami mencipta rangka pangkalan data kami, arahan SQL pertama menggunakan contoh java.sql.  - 3

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 asas BaseModel. 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: Bahagian 3. Kami mencipta rangka pangkalan data kami, arahan SQL pertama menggunakan contoh java.sql.  - 4
  • Class.forName()memuatkan kelas dan mendaftarkannya dengan DriverManager;
  • DriverManager.getConnection()akan kembali Connection– sambungan ke pangkalan data yang dinyatakan dalam hujah kaedah dan menggunakan pemacu JDBC yang sepadan (yang dimuatkan menggunakan Class.forName()).
  • createStatement()akan mengembalikan kepada kami Statementobjek yang berdasarkannya kami boleh membentuk pertanyaan kepada pangkalan data. Terdapat juga:
      CallableStatementuntuk memanggil fungsi dan prosedur SQL DBMS sendiri (ia dipanggil disimpan).
    • PreparedStatementmemudahkan penciptaan pertanyaan berparameter dan kelompok.
  • Mempunyai "di tangan" statementakan execute()membolehkan anda menghantar permintaan dalam bentuk perintah bahasa pertanyaan SQL terus ke pelaksanaan DBMS dan mengembalikan respons dalam bentuk ResultSet. Untuk kemudahan terdapat:
    • executeQuery()– untuk membaca data daripada DBMS.
    • executeUpdate()– untuk mengubah suai data dalam DBMS.
  • Sambutan pelayan itu sendiri ResultSetboleh diproses dalam bentuk dengan mengulangi first(), last(), next()dan seterusnya. Kita boleh mendapatkan medan hasil individu melalui pengambil: getInteger(), getString()...
Perlu diingat bahawa selepas bekerja dengan DBMS, untuk menjimatkan sumber, adalah dinasihatkan untuk menutup objek di belakang anda (dalam susunan yang betul!) ResultSet, Statementdan Connectionuntuk 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 Statementdan semua ResultSetditerima 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;
Bahagian 3. Kami mencipta rangka pangkalan data kami, arahan SQL pertama menggunakan contoh java.sql.  - 5 Repositori baharu akan mewarisi daripada kelas BaseTabledan 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:
  1. Mari tambah satu lagi keupayaan untuk bekerja dengan jadual dalam bentuk kaedah antara muka baharu.
  2. Seterusnya, dalam kelas yang melaksanakan antara muka, kami akan menerangkan pelaksanaan perisian dalam kaedah baharu yang dihasilkan oleh antara muka.
Contoh repositori untuk 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: Bahagian 3. Kami mencipta rangka pangkalan data kami, arahan SQL pertama menggunakan contoh java.sql.  - 6 Selain repositori dan model, kami juga telah mencipta kelas StockExchangeDBuntuk 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: Bahagian 3. Kami mencipta rangka pangkalan data kami, arahan SQL pertama menggunakan contoh java.sql.  - 7

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.

pautan yang berguna

Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION