数据库
数据库,是数据的集合,由一张张数据表组成,用来存放数据。
每一张表都有一个唯一标识,即主键,标识数据的唯一性。表与表之间可以 通过主键来互相联系,就是数据能够对应匹配,称之为联结。
什么是SQLite
SQLite是一个软件库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。SQLite是一个增长最快的数据库引擎。
SQLite 引擎不是一个独立的进程,可以按应用程序需求进行静态或动态连接。SQLite 直接访问其存储文件。
为什么要用SQLite
不需要一个单独的服务器进程或操作的系统(无服务器的)。
SQLite 不需要配置,这意味着不需要安装或管理。
一个完整的 SQLite 数据库是存储在一个单一的跨平台的磁盘文件。
SQLite 是非常小的,是轻量级的,完全配置时小于 400KiB,省略可选功能配置时小于250KiB。
SQLite 是自给自足的,这意味着不需要任何外部的依赖。
SQLite 事务是完全兼容 ACID 的,允许从多个进程或线程安全访问。
SQLite 支持 SQL92(SQL2)标准的大多数查询语言的功能。
SQLite 使用 ANSI-C 编写的,并提供了简单和易于使用的 API。
SQLite 可在 UNIX(Linux, Mac OS-X, Android, iOS)和 Windows(Win32, WinCE, WinRT)中运行。
安装sql ,可以先用命令查询自己系统是否安装过sqlite3
SQLite Download Page
解压压缩包
1 2 3 4
| $ tar xvzf sqlite-autoconf-3401502.tar.gz $ cd sqlite-autoconf-3401502 $ ./configure $ sudo make install
|
SQLite 注释是附加的注释,可以在 SQLite 代码中添加注释以增加其可读性,他们可以出现在任何空白处,包括在表达式内和其他 SQL 语句的中间,但它们不能嵌套。
SQL 注释以两个连续的 “-“ 字符(ASCII 0x2d)开始,并扩展至下一个换行符(ASCII 0x0a)或直到输入结束,以先到者为准。
在Qt中使用SQLite数据库
要使用SQL的类定义,需要引用相关头文件
1 2 3
| #include <QSqlDatabase> #include <QSqlError> #incldue <QSqlQuery>
|
在.pro文件中加入sql模块
查询驱动
1 2 3 4 5 6 7 8 9 10 11
| #include <QApplication> #include <QSqlDatabase> #include <QDebug> #include <QStringList> int main() { QApplication a(argc, argv); QStringList drivers = QSqlDatabase::drivers(); foreach(QString driver, drivers) qDebug() << driver; }
|
连接数据库
数据库连接使用连接名来定义,而不是使用数据库名,可以向相同的数据库创建多个连接。QSqlDatabase也支持默认连接的概念,默认连接就是一个没有命名的连接。在使用QSqlQuery或者QSqlQueryModel的成员函数时需要指定一个连接名作为参数,如果没有指定,那么就会使用默认连接。
1 2 3 4 5 6 7 8 9 10
| QSqlDatabase database; if(QSqlDatabase::contains("qt_sql_default_connection")) { database = QSqlDatabase::database("qt_sql_default_connection"); }else{ database = QSqlDatabase::addDatabase("QSQLITE"); database.setDatabaseName("myDataBase.db"); database.setUserName("moss"); database.setPassword("123456"); }
|
打开数据库
使用open()打开数据库,并判断是否成功。注意,在第一步检查连接是否存在时,如果连接存在,则在返回这个连接的时候,会默认将数据库打开。
1 2 3 4 5 6 7 8
| if (!database.open()) { qDebug() << "Error: Failed to connect database." << database.lastError(); } else { }
|
关闭数据库
数据库操作完成后,最好关闭。
执行sql语句
QSqlQuery类提供了一个接口,用于执行SQL语句和浏览查询的结果集。要执行一个SQL语句,只需要简单的创建一个QSqlQuery对象,然后调用QSqlQuery::exec()函数即可。
1 2 3 4
| QSqlQuery query; query.exec("select * from student"); query.exec("insert into student (id, name) values (1, 'LI')");插入一条记录
|
处理数据
同一时间插入多条记录,可以使用占位符来完成。Qt支持两种占位符:名称绑定和位置绑定。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| query.prepare("insert into student (id, name) values (:id, :name)"); int idValue = 1; QString nameValue = "Li"; query.bindValue(":id", idValue); query.bindValue(":name", nameValue); query.exec();
query.prepare("insert into student (id, name) values (?, ?)"); int idValue = 1; QString nameValue = "Li"; query.addBindValue(idValue); query.addBindValue(nameValue); query.exec();
|
当要插入多条记录时,只需要调用QSqlQuery::prepare()一次,然后使用多次bindValue()或者addBindValue()函数来绑定需要的数据,最后调用一次exec()函数就可以了。其实,进行多条数据插入时,还可以使用批处理进行:
1 2 3 4 5 6 7 8 9
| query.prepare("insert into student (id, name) values (?, ?)"); QVariantList ids; ids << 1 << 2 << 3; query.addBindValue(ids); QVariantList names; names << "Li" << "Wang" << "Liu"; query.addBindValue(names); if(!query.execBatch()) qDebug() << query.lastError();
|
修改数据
1 2 3 4 5 6 7 8 9 10 11 12 13
| QString update_sql = "update student set name = :name where id = :id";
sql_query.prepare(update_sql); sql_query.bindValue(":name", "Qt"); sql_query.bindValue(":id", 1); if(!sql_query.exec()) { qDebug() << sql_query.lastError(); } else { qDebug() << "updated!"; }
|
部分查询数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| QString select_sql = "select id, name from student"; if(!sql_query.exec(select_sql)) { qDebug()<<sql_query.lastError(); } else { while(sql_query.next()) { int id = sql_query.value(0).toInt(); QString name = sql_query.value(1).toString(); qDebug()<<QString("id:%1 name:%2").arg(id).arg(name); } }
|
select , , … from ;//部分查询指令
查询全部数据
QSqlQuery提供了对结果集的访问,可以一次访问一条记录。当执行完exec()函数后,QSqlQuery的内部指针会位于第一条记录前面的位置。必须调用一次QSqlQuery::next()函数来使其前进到第一条记录,然后可以重复使用next()函数来访问其他的记录,直到该函数的返回值为false,
1 2 3 4
| while(query.next()) { qDebug() << query.value(0).toInt() << query.value(1).toString(); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| QString select_all_sql = "select * from student"; sql_query.prepare(select_all_sql); if(!sql_query.exec()) { qDebug()<<sql_query.lastError(); } else { while(sql_query.next()) { int id = sql_query.value(0).toInt(); QString name = sql_query.value(1).toString(); int age = sql_query.value(2).toInt(); qDebug()<<QString("id:%1 name:%2 age:%3").arg(id).arg(name).arg(age); } }
|
语句select * from ;查询所有数据用 * 表示。
用while(sql_query.next())用来遍历所有行。同样用value()获得数据。
(3)查询最大id
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| QString select_max_sql = "select max(id) from student"; int max_id = 0; sql_query.prepare(select_max_sql); if(!sql_query.exec()) { qDebug() << sql_query.lastError(); } else { while(sql_query.next()) { max_id = sql_query.value(0).toInt(); qDebug() << QString("max id:%1").arg(max_id); } }
|
这个就是在语句中用max来获取最大值。
删除与清空
(1)删除一条数据
1 2 3 4 5 6 7 8 9 10 11
| QString delete_sql = "delete from student where id = ?"; sql_query.prepare(delete_sql); sql_query.addBindValue(0); if(!sql_query.exec()) { qDebug()<<sql_query.lastError(); } else { qDebug()<<"deleted!"; }
|
语句delete from where =
delete用于删除条目,用where给出限定条件。例如此处是删除 id = 0的条目。
(2)清空表格(删除所有)
1 2 3 4 5 6 7 8 9
| QString clear_sql = "delete from student"; sql_query.prepare(clear_sql); if(!sql_query.exec()) { qDebug() << sql_query.lastError(); } else { qDebug() << "table cleared";
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| #ifndef MAINWINDOW_H #define MAINWINDOW_H
#include <QMainWindow> #include <QSqlDatabase> #include <QSqlQuery> #include <QSqlTableModel> #include <QTableView> #include <QComboBox> #include <QSqlQueryModel> #include <QGridLayout> class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow();
private: QSqlDatabase sqldatabase; QSqlQueryModel *sqlQueryModel; QComboBox *comboBox; QGridLayout *gridLayout; QSqlTableModel *model;
}; #endif
|
mainwindow.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
| #include "mainwindow.h" #include <QDebug> #include <QSqlError> #include <QSqlRecord> #include <QApplication> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { this->setGeometry( 0, 0, 800, 480); QStringList drivers = QSqlDatabase::drivers(); foreach(QString driver, drivers){ qDebug()<<driver; } if(QSqlDatabase::contains("qt_sql_default_connection")) { sqldatabase = QSqlDatabase::database("qt_sql_default_connection"); }else{ sqldatabase = QSqlDatabase::addDatabase("QSQLITE"); sqldatabase.setDatabaseName("la.db"); } if (!sqldatabase.open()) { qDebug() << "Error: Failed to connect database." << sqldatabase.lastError(); } else { qDebug() << "连接成功" << endl; } QSqlQuery query; if(sqldatabase.tables().contains("users")) { qDebug() << "table users already exists!"; } else {
QString cmd = "create table users(user varchar(50) primary key, pwd varchar(50),phone varchar(50), email varchar(50), identity varchar(20));";
if(!query.exec(cmd)) { qDebug() << "create users table error!"; } } if(sqldatabase.tables().contains("informations")) { qDebug() << "table informations already exists!"; } else { if(!query.exec("create table informations(id int primary key,name varchar(20));")) { qDebug() << "create informations table error!"; } } QString cmd = QString("insert into informations values(3, 'qiadu')"); qDebug() << cmd; if(query.exec(cmd)) { qDebug() << "insert ok!";
} else { qDebug() << "insert error!"; } query.exec("select * from informations"); while(query.next()) { qDebug() << query.value(0).toInt()<< query.value(1).toString(); } } MainWindow::~MainWindow() { sqldatabase.close(); }
|

SQL查询模型QSqlQueryModel
QSqlQueryModel提供了一个基于SQL查询的只读模型。
1 2 3 4 5 6 7 8
| QSqlQueryModel *model = new QSqlQueryModel(this); model->setQuery("select * from student"); model->setHeaderData(0, Qt::Horizontal, tr("学号")); model->setHeaderData(1, Qt::Horizontal, tr("姓名")); model->setHeaderData(2, Qt::Horizontal, tr("课程")); ui->tableView->setModel(model); ui->tableView->verticalHeader()->setHidden(true); ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
|
这里要注意,其实QSqlQueryModel中存储的是执行完setQuery()函数后的结果集,所以视图中显示的是结果集的内容。QSqlQueryModel中还提供了columnCount()返回一条记录中字段的个数;rowCount()返回结果集中记录的条数;record()返回第n条记录;index()返回指定记录的指定字段的索引;clear()可以清空模型中的结果集。
eg:
1 2
| //.pro文件 Qt += core gui sql
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QSqlError> #include <QSqlQuery> #include <QSqlDatabase> #include <QSqlQueryModel> #include <QSqlTableModel> #include <QDataWidgetMapper> #include <QTableView> class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); QSqlDatabase sqlDatabase; QSqlQueryModel *model; QDataWidgetMapper *dataWidgetMapper; QTableView *tableview; }; #endif
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| #include "mainwindow.h" #include <QDebug> #include <QSqlError> #include <QApplication> #include <QSqlRecord> #include <QHeaderView> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { this->setGeometry( 0, 0, 800, 480);
QStringList drivers = QSqlDatabase::drivers(); foreach(QString driver, drivers) { qDebug()<<driver; } sqlDatabase = QSqlDatabase::addDatabase( "QSQLITE"); sqlDatabase.setDatabaseName("excel.db"); sqlDatabase.setUserName("moss"); sqlDatabase.setPassword("123456"); if(!sqlDatabase.open()) { qDebug()<<"连接数据库失败"<<sqlDatabase.lastError()<<endl; }else{ qDebug()<<"连接成功"<<endl; } QSqlQuery query(sqlDatabase); if(sqlDatabase.tables().contains("informations")) { qDebug() << "table information already exists!"; } else { if(!query.exec("create table informations(str double primary key, dis double));")) { qDebug() << "create informations table error!"; } } QString cmd = QString("insert into informations values(32, 2.2)"); qDebug() << cmd; if(query.exec(cmd)) { qDebug() << "insert ok!"; } else { qDebug() << "insert error!"; } query.exec("select * from informations"); while(query.next()) { qDebug() << query.value(0).toInt()<< query.value(1).toString(); } model = new QSqlQueryModel(this); model->setQuery("select * from informations"); model->setHeaderData(0, Qt::Horizontal, tr("强度")); model->setHeaderData(1, Qt::Horizontal, tr("位移")); QTableView *tableview = new QTableView; tableview->setModel(model); tableview->show(); } MainWindow::~MainWindow() { sqlDatabase.close(); }
|
SQL表格模型QSqlTableModel
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| #include "mainwindow.h" #include <QDebug> #include <QSqlError> #include <QApplication> #include <QSqlRecord> #include <QHeaderView>
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { this->setGeometry( 0, 0, 800, 480);
QStringList drivers = QSqlDatabase::drivers(); foreach(QString driver, drivers) { qDebug()<<driver; } sqlDatabase = QSqlDatabase::addDatabase( "QSQLITE"); sqlDatabase.setDatabaseName("excel.db"); sqlDatabase.setUserName("moss"); sqlDatabase.setPassword("123456"); if(!sqlDatabase.open()) { qDebug()<<"连接数据库失败"<<sqlDatabase.lastError()<<endl; }else{ qDebug()<<"连接成功"<<endl; } QSqlQuery query(sqlDatabase); if(sqlDatabase.tables().contains("informations")) { qDebug() << "table information already exists!"; } else { if(!query.exec("create table informations(str double primary key, dis double));")) { qDebug() << "create informations table error!"; } } QString cmd = QString("insert into informations values(32, 2.2)"); qDebug() << cmd; if(query.exec(cmd)) { qDebug() << "insert ok!"; } else { qDebug() << "insert error!"; } query.exec("select * from informations"); while(query.next()) { qDebug() << query.value(0).toInt()<< query.value(1).toString(); } QTableView *tableview = new QTableView; QSqlTableModel * tablemodel = new QSqlTableModel(this); tablemodel->setTable("informations"); tablemodel->select(); tablemodel->setEditStrategy(QSqlTableModel::OnManualSubmit); tableview->setModel(tablemodel); tableview->verticalHeader()->setHidden(true); tableview->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); tableview->show(); } MainWindow::~MainWindow() { sqlDatabase.close(); }
|