Selamat siang, Khabrovsk! Dalam artikel ini, saya ingin berbicara tentang pengalaman saya menyederhanakan interaksi dengan database SQL ketika mengembangkan aplikasi desktop menggunakan kelas QSqlRelationalTableModel dari perpustakaan lintas platform Qt.
Prolog
Saya bertemu Qt ketika saya masih mahasiswa tahun pertama, baru mulai program di C ++, pada saat yang sama saya menjadi sangat tertarik pada perpustakaan dan, sejak itu, telah mengikuti pembaruannya. Beberapa bulan yang lalu, di tempat kerja, mereka memberi saya TOR di mana perlu untuk mengembangkan aplikasi yang berinteraksi dengan database SQLite. Struktur pangkalan diperbaiki dan diketahui oleh saya dari TK sebelumnya.
Aplikasi harus dapat dengan mudah menyediakan data yang disimpan kepada operator dalam basis data, memungkinkan menambahkan catatan baru, menghapus dan mengubah yang sudah ada.
Selanjutnya, saya akan menjelaskan secara singkat proses pengembangan dengan potongan kode dan mencoba menjelaskan secara wajar mengapa dalam hal ini pilihan dibuat mendukung
QSqlRelationalTableModel .
Pengembangan dimulai
Awalnya, diputuskan untuk membangun interaksi dengan database menggunakan query database sederhana, yaitu
SELECT ,
INSERT ,
DELETE , yang memungkinkan Anda untuk mengimplementasikan semua fungsi aplikasi yang diperlukan.
Untuk melakukan ini, kita memerlukan kelas
QSqlDatabase dan
QSQlQuery :
QSqlDatabase db;
Setelah itu, semua operasi pada database dilakukan sebagai berikut:
Pernyataan pilih dijalankan dengan cara yang sama, kecuali bahwa data masih perlu diterima dan diletakkan di suatu tempat:
QString query = "SELECT id, ka FROM Table"; QSqlQuery sqlQ(db); if(!sqlQ.exec(query)) { qDebug() << "query failed..."; return; }
Hapus-pernyataan dijalankan dengan cara yang persis sama dengan Sisip karena mereka tidak menghasilkan apa-apa.
Baiklah, apa masalahnya?
Dan kebenarannya adalah, Anda dapat mengimplementasikan semuanya melalui ungkapan dan pertanyaan ini,
mengapa kita membutuhkan model?Ketika kita memiliki satu tabel yang tidak terkait, semuanya tampak sangat sederhana dan tidak memerlukan pengenalan alat tambahan. Sekarang bayangkan kita memiliki tabel seperti itu, misalnya, 5, masing-masing dengan 5 kolom, tidak termasuk id. Dan masing-masing memiliki koneksi dengan yang sebelumnya menggunakan
kunci asing via
id , yaitu saat menghapus, perlu untuk kaskade untuk menghapus semua catatan "anak". Ini mengarah ke sejumlah besar permintaan, pekerjaan aplikasi melambat secara signifikan, terlebih lagi, perlu memperbarui tabel dan presentasinya di antarmuka setiap kali, yang mengarah pada penulisan fungsi tambahan untuk memperbarui, penampilan bug atau risiko terjadinya mereka, dan secara umum mengurangi keterbacaan kode.
Untuk alasan ini, selama proses pengembangan, saya harus meninggalkan konsep menggunakan query
SQL kosong.
Pilihan lebih lanjut dibuat mendukung
QSqlRelationalTableModel bersama dengan
QTableView . Ada versi yang lebih sederhana dari implementasi model -
QSqlTableModel , yang pertama diwarisi darinya, ia memiliki semua metode yang sama, tetapi menambahkan kemampuan untuk membuat koneksi
QSqlRelation , yang sangat nyaman jika pengguna tidak perlu menunjukkan id rekaman, tetapi nama catatan "induk" yang dengannya terhubung.
Mari kita lihat implementasi dengan model
Berikut adalah beberapa kutipan pod yang menunjukkan implementasi model / tampilan.
Dalam file header:
QSqlRelationalTableModel *model;
Dalam konstruktor:
Baris di bawah ini berisi salah satu fitur yang paling nyaman dan keuntungan dari model atas kueri sql - itu mengedit, menambah, menghapus, tergantung pada konteksnya, data dalam tabel sql ketika mengubah dari ke QTableView. Kemudahannya adalah Anda tidak perlu lagi mengontrol kebenaran penghapusan data kaskade dan memutakhirkannya dalam satu QTableView.
model->setEditStrategy(QSqlRelationalTableModel::OnFieldChange);
Berikutnya hadir fitur nyaman lain yang disediakan oleh kelas ini: koneksi dibuat antara dua kolom tabel yang berbeda:
Selanjutnya, semuanya lebih standar: select () akan menjalankan ekspresi SELECT, dan setHeaderData () akan mengatur teks di header QTableView:
model->select(); model->setHeaderData(0, Qt::Horizontal, tr("id")); model->setHeaderData(1, Qt::Horizontal, tr("id_sub")); model->setHeaderData(2, Qt::Horizontal, tr("count")); model->setHeaderData(3, Qt::Horizontal, tr("number")); model->setHeaderData(4, Qt::Horizontal, tr("data_word")); model->setHeaderData(5, Qt::Horizontal, tr("time")); model->setHeaderData(6, Qt::Horizontal, tr("name")); model->setHeaderData(7, Qt::Horizontal, tr("description")); ui->tableView->setModel(model);
Sekarang model dan tableView bekerja bersama dan menjalankan fungsinya. Dengan tautan ke
github, semua sumber akan ditinggalkan, di dalamnya saya menerapkan penambahan entri ke model, menghapusnya, serta filter.
Kesimpulan
Dalam artikel ini, saya ingin mendorong semua orang yang sudah bekerja dengan database di Qt untuk mengabaikan pertanyaan sql untuk proyek yang setidaknya memiliki kompleksitas sedang dan beralih ke bekerja dengan model untuk menyederhanakan hidup mereka, membuat kode lebih mudah dibaca dan universal, yah, lakukan saja sesuatu yang baik dan baru.
Itu saja! Saya berharap pengalaman saya dengan kelas-kelas ini akan membantu pembaca berhasil memecahkan masalah yang sama!